elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [SOLUCIONADO]libreria ZedGraph
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [SOLUCIONADO]libreria ZedGraph  (Leído 1,042 veces)
01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
[SOLUCIONADO]libreria ZedGraph
« en: 22 Agosto 2019, 17:45 »

Saludos!

Amigos con respecto a la libreria ZedGraph, estoy tratado de crear una grafica con respecto a las horas transcurridas durante un dia, los datos los obtengo a traves de una base de datos.

la tabla en la cual estoy obteniendo los datos es de la siguiente forma:


como notaran hay 8 campos de temperaturas, llamados vin0....vin7 y tambien el campo hora.

lo que pretendo hacer es que en el eje XAxis de la grafica se muestren las horas transcurridas, la cual estan guardas en la tabla de la base de datos, y en el eje YAxis se muestren los registros de las temperaturas, este es mi codigo :

Código
  1. Option Strict Off
  2. Option Explicit On 'Permiten declaracion de varias variables'
  3. Imports VB = Microsoft.VisualBasic
  4. Imports ZedGraph
  5. Imports MySql.Data.MySqlClient
  6.  
  7. Public Class Form1
  8.  
  9.    Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
  10.        Me.CenterToScreen()
  11.        Try
  12.            Conexion.ConnectionString = connStr
  13.            Conexion.Open()
  14.            Me.Text = "CONECTADO"
  15.        Catch ex As Exception
  16.            MsgBox(ex.Message)
  17.        Finally
  18.            Conexion.Close()
  19.        End Try
  20.        CreateGraph(ZedGraphControl1)
  21.    End Sub
  22.  
  23.    Private Sub CreateGraph(ByVal zgc As ZedGraphControl)
  24.  
  25.        Try
  26.            Dim query As String = "SELECT * from termocuplas"
  27.            Dim connection As New MySqlConnection(connStr)
  28.            Dim cmd As New MySqlCommand(query, connection)
  29.  
  30.            connection.Open()
  31.  
  32.            Dim reader As MySqlDataReader
  33.            reader = cmd.ExecuteReader()
  34.  
  35.            Dim list1 = New PointPairList()
  36.            Dim x As String
  37.            Dim y As String
  38.  
  39.            Dim myPane As GraphPane = zgc.GraphPane
  40.            myPane.Title.Text = "Termocupla"
  41.            myPane.XAxis.Title.Text = "Tiempo"
  42.            myPane.XAxis.Scale.MagAuto = False
  43.            myPane.YAxis.Title.Text = "Temperatura °C"
  44.            myPane.YAxis.Scale.MagAuto = False
  45.  
  46.            While reader.Read()
  47.                y = reader.GetString(2)
  48.                x = reader.GetString(11)
  49.                list1.Add(x, y)
  50.            End While
  51.  
  52.            Dim myCurve As LineItem = myPane.AddCurve("Termocupla Vapor", list1, Color.Red, SymbolType.None)
  53.            zgc.AxisChange()
  54.            reader.Close()
  55.            connection.Close()
  56.        Catch ex As Exception
  57.            Console.WriteLine(ex.Message)
  58.        End Try
  59.  
  60.    End Sub
  61.  
  62. End Class
  63.  

tengo el problema que no esta funconando de forma correcta, aqui una muestra:


como ven en el eje x se estan mostrando los valores de forma entera, y no en forma de la hora registrada, por ejemplo: 13:05:40 e igualmente para el eje Y, se esta mostrando los valores de forma entera, y no de la forma +38,85

que debo corregir para que funcione de la forma que quiero???

gracias de antemano!





« Última modificación: 28 Agosto 2019, 14:39 por 01munrra » En línea

NEBIRE


Desconectado Desconectado

Mensajes: 2.335


Ver Perfil
Re: libreria ZedGraph
« Respuesta #1 en: 23 Agosto 2019, 23:32 »

Por qué declaras como 'string', 'x' e 'y'?

Decláralos como 'single', vamos conc decimales aun que luego vengana a redondearse según el tamaño del gráfico, expuestos a un tamaño mayor, la precisión será con más detalle...
...Y cuando leas los datos (aunque por alguna razón estén guardados en formato de string en la bd, en un fichero o donde sea), tu haz la conversión al tipo single. Así tu 'list1' debe almacenar valores single...

Luego... en la gráfica obivamente debes tener un factor de escala para el eje X y otro factor de escala para el valor Y...
Esto es, si una hora ocupa en el gráfico 20 píxeles de ancho (por ejemplo),  quiere decir que tendrás 20 píxeles para mostrar 1 hora, luego 60 minutos, luego 3.600 segundos... por tanto un valor como: las 13:30:45, no aparecría dibujado distinto del valor 13:33:27 (por ejemplo), pués en cada píxel se deben acomodar 3 minutos.

No te preocupes, está bien, si toleras que se pueda hacer zoom, luego tendrás que para una hora, en vez de 20 píxeles, tuvieras por ejemplo 180, con lo cual ahora cada píxel podría acoger ya hasta 20 segundos (digamos que esa sería la precisión)....


En línea

01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
Re: libreria ZedGraph
« Respuesta #2 en: 24 Agosto 2019, 10:29 »

Muchas gracias por tu atención  y por tu recomendación,  lo editare  de la forma que me recomiendas.... y otra pregunta,  haber si se puede hacer con esta librería,  la intención  del eje X es que sea la hora:minutos:segundos,  entonces existirá  alguna forma de añadir una barra de tipo scrol a la gráfica generada, de tal forma que a medida que cargue los datos,  se puedan ver los días pasados???? Si me explico
En línea

NEBIRE


Desconectado Desconectado

Mensajes: 2.335


Ver Perfil
Re: libreria ZedGraph
« Respuesta #3 en: 24 Agosto 2019, 22:02 »

No he operado nunca con esa librería... desconozco si lo permite.

No obstante si está capacitada para mostrar la imagen, lo puedes implementar tú, aunque con algo mñás de trabajo claro.

... supongamos que el gráfico está a un zoom de 4 horas (que muestra solo 4 horas), entonces tu generas imágenes en bagkground desde las 0 hasta las 3:59:59, luego otra desde las 4 hasta las 7:59:59, luego... y al final la última 20:59:59.
Luego eres tú quien en un backbuffer va pegando lo correspondiente entre dos imágenes y finalmente lo vuelcas a donde lo presentas... el control tal como señalas con un scroll del tipo que sea, incluso un "fijar y arrastrar" (si no quieres perder tiempo en poner una interfaz gráfica para ello)... vamos básicamente como la sucesión de desplazamiento horizontal de un videojuego, solo que más sencillo pués solo son dos imágenes con las que lidiar en cada momento.

Tienes 6 imagenes suponiendo un zoom de 4 horas, para cubrir el día completo.
img0|img1|img2|...|img5

En cualquier momento dado, puede haber a lo sumo parte de 2 imágenes:
|......|......|

Se trata pués de seleccionar, cortar y pegar la parte correspondiente de cada imagen en el 'viewport'.

Viewport, con la mitad de dos imagenes:
...|...

Viewport con 5/6 de una imagen y 1/6 de la siguiente.
.....|.

Viewport con una imagen completa (como ahora la tienes)
|......|


Espero que te quede clara la idea de como lograrlo, si la propia librería no tiene capacidad para ello.
En línea

01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
Re: libreria ZedGraph
« Respuesta #4 en: 26 Agosto 2019, 16:30 »

Por qué declaras como 'string', 'x' e 'y'?

Decláralos como 'single', vamos conc decimales aun que luego vengana a redondearse según el tamaño del gráfico, expuestos a un tamaño mayor, la precisión será con más detalle...
...Y cuando leas los datos (aunque por alguna razón estén guardados en formato de string en la bd, en un fichero o donde sea), tu haz la conversión al tipo single. Así tu 'list1' debe almacenar valores single...

Luego... en la gráfica obivamente debes tener un factor de escala para el eje X y otro factor de escala para el valor Y...
Esto es, si una hora ocupa en el gráfico 20 píxeles de ancho (por ejemplo),  quiere decir que tendrás 20 píxeles para mostrar 1 hora, luego 60 minutos, luego 3.600 segundos... por tanto un valor como: las 13:30:45, no aparecría dibujado distinto del valor 13:33:27 (por ejemplo), pués en cada píxel se deben acomodar 3 minutos.

No te preocupes, está bien, si toleras que se pueda hacer zoom, luego tendrás que para una hora, en vez de 20 píxeles, tuvieras por ejemplo 180, con lo cual ahora cada píxel podría acoger ya hasta 20 segundos (digamos que esa sería la precisión)....

hey

lo he trabajado como single, mira esta parte:

Código:
Dim y As Single
Dim x As Single
Dim str As String

y los convierto en:
Código:
y = Convert.ToSingle(reader.GetString(2))
str = Replace(reader.GetString(11), ":", ".")
x = Convert.ToSingle(str)

como ves, a la hora estoy reemplazando el ":" por "."  ya que me al tratar de hacer:
Código:
x=Convert.ToSingle(reader.GetString(11))
y reader.GetString(11) = "13:33:27", no me hace nada, y no grafica nada, por ello hice esa conversion. ahora al hacerla convirtiendolo me esta graficando de la siguiente forma:


En línea

01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
Re: libreria ZedGraph
« Respuesta #5 en: 26 Agosto 2019, 19:28 »

ya le he mejorado un poco mas...... fijate en la imagen a continuación:


ya con respecto al eje 'Y' no creo que haga falta mejorarla, pero en el eje 'X' si hace falta, fijate en el codigo:

Código:
   Dim y As Single
            Dim x As Single

            If reader.Read Then
                While reader.Read()
                    y = Convert.ToSingle(Replace(reader.GetString(3), ".", ","))
                    x = Convert.ToSingle(Replace(reader.GetString(11), ":", "."))
                    list1.Add(x, y)
                End While
         End If

que me recomiendas para mejorar el eje 'X', en vista de que el sistema trabaja en hora militar, de 0 a 23 hrs, estoy tratando de que solo se muestre la unidad de hora y al hacer zoom se muestre minutos y segundos, tal cual esta sucediendo en la temperatura.
En línea

NEBIRE


Desconectado Desconectado

Mensajes: 2.335


Ver Perfil
Re: libreria ZedGraph
« Respuesta #6 en: 27 Agosto 2019, 16:08 »

...que me recomiendas para mejorar el eje 'X', en vista de que el sistema trabaja en hora militar, de 0 a 23 hrs, estoy tratando de que solo se muestre la unidad de hora y al hacer zoom se muestre minutos y segundos, tal cual esta sucediendo en la temperatura.
...
Te comentaba en el mensaje anterior, pero probablemente no te acomode buscar en la documentación de la librería si pueda devolver una imagen (un picture), para que tu solicitando todas las gráficas para un día, luego mediante operaciones gráficas puedas pegar a voluntad secciones en función del desplazamiento absoluto en el día.

De todos modos, veo en el gráfico, que muestra desde las 7 hasta las 14, es decir un tramo de 7 horas... la pregunta pertinente es: tiene alguna propiedad o método que permita hacer zoom (escalar), el eje X, por ejemplo para que tu puedas determinar que en el gráfico quepa solo una hora, 2, 4, 8, 24... es decir las que tu quieras?.
Me resultaría extraño, que la librería no permitiera ajustar la escala en ambos ejes.

En esa vista (de la última imagen), si acogiera solo una hora, sería magnifico, pués a ojo de buen cubero ocpa unos 750 píxels de ancho, así que cada píxel podría acoger a solo 5 segundos... lo que daría una muy buena precisión.

En última instancia, si la librería no permitiera ningún tipo de zoom (antes de intentar lo siguiente mira si de verdad la librería no lo permite, porque si lo permite lo que ahremos sería una sobrecarga innecesaria de trabajo), podemos manejarlo nosotros a nuestro antojo...

...hemos leído los datos de entrada, (sea cual sea el origen), y tenemos pués un array, una lista enlazada, etc... con los datos... por comodidad, voy a suponer que están en alojados en un array y que es una estructura de tipo puntof ...

Creando nuestro zoom artificial:
Código:
Estructura PuntoFlotante
  x as single
  y as single
fin estructura

dim puntos() as puntoflotante

funcion privada Escalar(por referencia P() as puntoflotante, EscalaX as single, EscalaY as single) as puntoflotante()
    dim k as long
    dim tmp() as puntoFlotante

    dimensionar array temporal tmp(0 to p.Lenght)
    bucle para k desde 0 a p.lenght
        tmp(k).x = (p(k).x * escalaX)
        tmp(k).y = (p(k).y * escalaY
    repetir

    devolver tmp
fin funcion

Ya hemos escalado los valores, ahora solo queda mandarlo para que sean dibujados...

Código:
' Tu tienes:
  while reader.read
     ...
     list1.add(x,y)
   end while

' después conviene escalarlo:
dim list2  tipo...?
 list2 = Escalar(list1, 3.25, 1)

' ahora lo enviás a dibujar:
... myPane.AddCurve(..., list2)

Nota que los valores de escala los he puesto un poco allá, con 3.25 el resultaod es que se estirará el eje x x 3.25 veces, en cambio como señalas la escala en el eje Y va bien, los dejamos en su propia esclaa 1.0...
Pudiera ocurrir dos cosas:
- Primero: Que la librería intérprete al revés la escala... si ves que se encoge en vez de ensancharse, cambia las multiplicaciones por divisiones.
- Segundo: Que la librería se empeñe (cabezonamente) en meter al completo el gráfico dentro del viewport de la gráfica. ...para ello entonces implica que estaría recorriendo la colección para tomar el valor mayor y menor y conforme a ellos generar un escalado interno para que se ajuste al tamaño del viewport. Desde fuera (para ti), el resultado es que el gráfico a pesar de nuestro escalado, se vería prácticamente igual, las diferencias serías las nimias de los redondeos. En tal caso, o la librería dispone de algún control de la misma que estás obviando por no leerte/buscar en la documentación, o simplemente es mala por dejar fijo un gráfico sin posibilidad de escalarlo y que recorte lo que no quepa...

p.d.:
Cuando veas que el escalado te funcione bien... , entonces se trata solo de ajustar que factores son los valores limitantes, esto es mira de limitar el factor máximo y minimo de escala.
Añades un scroll a la ventana y un label que diga Escala del eje X:  3.75  ...si el valor mínimo de escala fuera (pongamos)  0.01 y el valor máximo 100, como usas un scroll numérico sin decimales, tu señalas (para el scroll) el minimo a 1 y el máximo a 10000, el valor real de escala sabes que será: EscalaX = Scroll.Value / 100

Nota que cada vez que el usuario quisiera escalar, no ser´´ia preciso volver a leer los datos de origen... sería mejor disponer una función aparte, es decir tener dos funcionalidades, la lectura de datos, y la de escalado:

Código:
' lee datos dle origen, los almacena en list1 y los manda dibujar...
sub LeerDatos
   ...
   while reader.read
      ...
      list1.add(x,y)
  end while

  call Dibujar
fin sub

Y luego la de dibujar...
Código:
' escala y dibuja la gráfica...
Sub dibujar
    dim list2 as tipo?

   list2= Escalar(list1, EscalaX, EscalaY)
   ... myPane.AddCurve(..., list2)
Fin sub

ambos scrolls para escalar eje x e Y:
Código:
sub ScrollX_change(...)
   EscalaX = scrollx.value/100
   labelejeX.Text = "Factor de escala del eje X: " & escalaX.ToString
 
   Call dibujar
End sub

sub ScrollY_change(...)
   EscalaY = scrollY.value/100
   labelejeY.Text = "Factor de escala del eje Y: " & EscalaY.ToString
 
   Call dibujar
End sub
« Última modificación: 27 Agosto 2019, 16:25 por NEBIRE » En línea

01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
Re: libreria ZedGraph
« Respuesta #7 en: 27 Agosto 2019, 16:29 »

Saludos NEBIRE!!

con respecto al zoom, funciona perfect, en la grafica puedo acercar y ver los valores exactamente como estan almacenados en la base de datos, nunca habia graficado en ningun lenguaje, hasta ahora estoy aprendiendo de ello, mil gracias por tu ayuda.

he estado investigando en la web, no existe muchos ejemplos para Vb, solo se consiguen en C# vb.... estoy estudiando este codigo que hicieron, fijate en el link que posteare:

https://yazilimciyamektup.wordpress.com/tag/multiple-y-axis/

esta en ruso o aleman, algo asi..... al menos el codigo se puede entender un poco, segun he entendido, tengo que declarar al eje x como de tipo Date:

Código:
            myPane.XAxis.Type = ZedGraph.AxisType.Date
            myPane.XAxis.Scale.Format = "HH: mm: ss"
            myPane.XAxis.Scale.MajorUnit = DateUnit.Second

lo diferencia es que el obtiene la fecha actual del sistema, en mi caso tendria que convertir el campo de tipo time a TimeSpan sino me equivoco.
En línea

01munrra

Desconectado Desconectado

Mensajes: 281



Ver Perfil
Re: libreria ZedGraph
« Respuesta #8 en: 27 Agosto 2019, 19:47 »

Ya logre hacerlo, he aqui la respuesta por si alguien llegue a necesitarlo:
Código:
'Configuramos la Graph en el eje 'X' como tipo Date
myPane.XAxis.Type = ZedGraph.AxisType.Date
myPane.XAxis.Scale.Format = "HH:mm:ss"
myPane.XAxis.Scale.MajorUnit = DateUnit.Second
    .
    .
    .


Dim list1 = New PointPairList()
Dim y As Single
Dim x As Single
Dim c As Date

      If reader.Read Then
                While reader.Read()
                    y = Replace(reader.GetString(3), ".", ",")
                    c = Convert.ToDateTime(reader.GetString(11))
                    x = c.ToOADate()
                    list1.Add(x, y)
                End While
                reader.Close()
            End If

usando la funcion ToOADate() que nos sirve para Convertir el valor de esta instancia en la fecha/hora de Automation OLE equivalente.
« Última modificación: 27 Agosto 2019, 19:59 por 01munrra » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines