Autor
|
Tema: [SOLUCIONADO]libreria ZedGraph (Leído 4,942 veces)
|
01munrra
Desconectado
Mensajes: 282
|
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 : Option Strict Off Option Explicit On 'Permiten declaracion de varias variables' Imports VB = Microsoft.VisualBasic Imports ZedGraph Imports MySql.Data.MySqlClient Public Class Form1 Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize Me.CenterToScreen() Try Conexion.ConnectionString = connStr Conexion.Open() Me.Text = "CONECTADO" Catch ex As Exception MsgBox(ex.Message) Finally Conexion.Close() End Try CreateGraph(ZedGraphControl1) End Sub Private Sub CreateGraph(ByVal zgc As ZedGraphControl) Try Dim query As String = "SELECT * from termocuplas" Dim connection As New MySqlConnection(connStr) Dim cmd As New MySqlCommand(query, connection) connection.Open() Dim reader As MySqlDataReader reader = cmd.ExecuteReader() Dim list1 = New PointPairList() Dim x As String Dim y As String Dim myPane As GraphPane = zgc.GraphPane myPane.Title.Text = "Termocupla" myPane.XAxis.Title.Text = "Tiempo" myPane.XAxis.Scale.MagAuto = False myPane.YAxis.Title.Text = "Temperatura °C" myPane.YAxis.Scale.MagAuto = False While reader.Read() y = reader.GetString(2) x = reader.GetString(11) list1.Add(x, y) End While Dim myCurve As LineItem = myPane.AddCurve("Termocupla Vapor", list1, Color.Red, SymbolType.None) zgc.AxisChange() reader.Close() connection.Close() Catch ex As Exception Console.WriteLine(ex.Message) End Try End Sub End Class
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 pm por 01munrra »
|
En línea
|
|
|
|
Serapis
|
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
Mensajes: 282
|
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
|
|
|
|
Serapis
|
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
Mensajes: 282
|
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: Dim y As Single Dim x As Single Dim str As String
y los convierto en: 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: 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
Mensajes: 282
|
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: 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
|
|
|
|
Serapis
|
...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: 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... ' 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: ' 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... ' 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: 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 pm por NEBIRE »
|
En línea
|
|
|
|
01munrra
Desconectado
Mensajes: 282
|
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: 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
Mensajes: 282
|
Ya logre hacerlo, he aqui la respuesta por si alguien llegue a necesitarlo: '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 pm por 01munrra »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[SOLUCIONADO]problema al crear imagen con libreria GD
PHP
|
H4RR13R
|
0
|
1,548
|
25 Febrero 2008, 21:29 pm
por H4RR13R
|
|
|
[solucionado] libreria para obtener los users de linux?
Programación C/C++
|
curiosodigital
|
4
|
5,690
|
15 Septiembre 2010, 17:33 pm
por curiosodigital
|
|
|
Libreria integrar captura de webcam con Qt4 (SOLUCIONADO)
Programación C/C++
|
paju1986
|
0
|
3,765
|
22 Diciembre 2010, 12:32 pm
por paju1986
|
|
|
No puedo correr el codigo por restriccion de libreria [SOLUCIONADO INSTALAR JDK]
Java
|
dato000
|
3
|
8,220
|
15 Febrero 2011, 22:03 pm
por dato000
|
|
|
Duda sobre la libreria java.util.*(solucionado)
Java
|
Senior++
|
2
|
7,127
|
15 Noviembre 2012, 18:55 pm
por Senior++
|
|