2010-09-17 28 views
14

Actualmente estoy usando la creación de gráficos dentro de .NET usando System.Windows.Forms.DataVisualization.Charting.Chart. Hasta ahora parece muy poderoso y funciona muy bien. Sin embargo, hay un gran problema en términos de cómo se calcula automáticamente los intervalos. Utilizo una gran cantidad de valores double, y en bibliotecas como ZedGraph, maneja esto perfectamente. Selecciona min/max/interval muy bien. Sin embargo, en MS Chart, puede seleccionar 206.3334539832 como mínimo e intervalos de precisión decimal similar. Obviamente, esto se ve bastante feo.Precisión de intervalo automático en MS Chart

Por lo tanto, traté simplemente de hacer el formato de eje {0.00} y funciona muy bien cuando carga el gráfico. Excepto cuando haces zoom, necesitas una mayor precisión, tal vez con 4 decimales en lugar de 2. Parece que estoy atorado con 9 lugares decimales todo el tiempo, o bien un número fijo constante que puede romperse cuando alguien requiere una mayor precisión. Prefiero que recoja la precisión según el nivel de zoom aplicado actualmente. Las bibliotecas como ZedGraph y Dundas (¡que creo que MS está usando!) Tienden a elegir buenos valores que cambian a medida que se acercan y alejan.

¿Hay alguna manera de hacer que los intervalos cambien la precisión a medida que cambia el marco del zoom? Probablemente es una propiedad simple que he configurado mal, pero es difícil de decir con los millones de propiedades que tiene esta cosa (especialmente cuando hay alrededor de 14 lugares que representan el concepto de Intervalo).

+2

yo sepa, los controles de creación de gráficos se basan en controles Dundas. Microsoft adquirió los componentes de visualización de datos de Dundas hace algún tiempo. Más información [aquí] (http://blogs.msdn.com/b/bimusings/archive/2007/06/04/microsoft-acquires-dundas-s-data-visualization-components-sql-2008-news-download- ctp3.aspx) – CGK

+0

No hay imágenes en su edición? – noelicus

+0

@noelicus Lo siento, nuevo trabajo desde entonces y esas imágenes fueron eliminadas en algún momento (aparentemente esto fue antes de que SO permita carga de imágenes). He eliminado la edición por ahora. Voy a ver si puedo encontrar una copia de esas imágenes y actualizar esta pregunta si puedo. – drharris

Respuesta

5

tuve exactamente el mismo problema al hacer zoom. Agregué el código para formatear las etiquetas del eje y llamarlo desde el controlador de Paint. Los objetos Vista del eje tienen una propiedad IsZoomed y tienen funciones para obtener los límites del eje actual (GetViewMinimum/Maximum). Establecí Axis LabelStyle.Format en "N" para todos los casos, a menos que el rango Max-Min = sea menor que 1. Luego configuré el formato en "F #", donde # se calcula en función del rango del eje.

# = Convert.ToInt32(Math.Abs(Math.Log10(range) - .5)) + 1; 
+0

¡Muchas gracias por señalar GetViewMinimum/Maximum! Estas son probablemente las funciones que estaba buscando. Intentaré esto pronto, y si funciona para mi caso, restableceré mi recompensa anterior y se la daré. También gracias por el código para obtener decimales: después de algunas pruebas en WolframAlpha, parece generar la cantidad perfecta de decimales. – drharris

+0

Olvidé informar, pero finalmente tuve tiempo para implementar esto y funciona PERFECTAMENTE. Todavía creo que el control en sí debería manejar este tipo de lógica (si los proyectos de código abierto como ZedGraph pueden hacerlo, seguramente MS/Dundas sí). He restablecido la recompensa original en esta pregunta, ya que esto me ahorra muchos dolores de cabeza de clientes insatisfechos. Lo otorgaré tan pronto como SO me lo permita. – drharris

1

Después de haber jugado con el control de gráfico no he podido encontrar una solución simple a su problema. Sin embargo, lo siguiente puede ayudar:

¿Ha considerado usted mismo establecer los valores máximo y mínimo para los ejes usted mismo? Si redondea los valores máximos y mínimos reales al número "redondo" sensible más cercano (5, 10, 0.5, 0.01), esto debería hacer que los intervalos calculados sean un poco más amigables.

Entiendo que esta no es una solución ideal, pero al elegir cuidadosamente los valores máximos y/o mínimos, puede asegurarse de que los intervalos sean números "más agradables". Si el rango de sus ejes es, por ejemplo, divisible por 2, 5 & 10, debería resultar en intervalos bastante agradables.

+0

Intenté configurar el valor mínimo y máximo, pero estos gráficos se utilizan para el análisis, y tan pronto como se acerca a una región personalizada, pierde los números redondos bonitos y vuelve a este comportamiento no deseado. Además, establecer el mínimo en -10 a veces resulta en -10.00000023 o similar. Entonces, estás a mitad de camino allí; arregla la pantalla inicial, pero con todo el zoom que sucederá, no es una solución completa al problema. Aunque es bueno saber que no soy el único. – drharris

0

para proporcionar el resultado con un costo mínimo que puede utilizar el formato científico exponencial

+0

Si esta fuera una aplicación interna utilizada solo por personas con mentalidad científica, ¡sería genial! Sin embargo, tenemos una base de usuarios que va de profesor universitario a agricultor. Enseñar a algunas de estas personas a leer el formato exponencial sería casi imposible. Además, el uso de números científicos no evita el problema de demasiados lugares decimales (como en 2.6666684583e-4) – drharris

+0

Solo use string.Format ("{0: e2}", 123.456789). También intente aplicar el formateador de convertidor personalizado. – gabba

1

Por qué no modificar una cadena de formato de número.

Crear cadena de formato

string formatString = "{0.00"; 

Identificar el nivel de zoom, dicen zoomLevel = 2;

formatString = formatString.PadRight(5+zoomLevel, '0'); 
formatString += "}"; 

Ahora use este formato en la leyenda del eje. Use el generador de cadenas o alguna forma mejor de modificar la cadena de formato.

+0

El problema es que el "nivel de zoom" tiene poco significado. La escala no siempre será la misma (a veces, el eje X puede tener un rango de 100-120 y otras veces de 0 a 4000). Además, el usuario puede auto-seleccionar una ventana de zoom, lo que significa que no hay una forma explícita de determinar el número de lugares decimales para formatear. Buena respuesta en teoría, pero simplemente no coincide con el modelo de objeto aquí. – drharris

0

Puede adjuntar a personalizar evento. A partir de ahí, se pueden modificar las etiquetas en el eje x:

var xAxisLabels = chart1.ChartAreas[0].AxisX.CustomLabels; 
... 
xAxisLabels[0].Text = ... 

conjunto min. y max. valores:

chart1.ChartAreas[0].AxisX.Maximum = ...; 

etc.

0

puede actualizar dinámicamente el máximo y el mínimo basado en el conjunto de datos.cada vez que el usuario amplía, usted hace una PROSPECHA en cada punto y obtiene las estadísticas y en función de ese conjunto su máximo y mínimo

+0

¿Código? ¿Cómo detectar cuando el usuario amplía? ¿Cómo solo recuperar los puntos que están en la ventana mientras el zoom está activo? – drharris

0

ayuda a establecer el IntervalOffset del eje, aquí un ejemplo:

Private Sub chMap_AxisViewChanged(sender As System.Object, e As System.Windows.Forms.DataVisualization.Charting.ViewEventArgs) Handles chMap.AxisViewChanged 
    'the grid ticks are rounded values 
    e.Axis.IntervalOffset = -e.Axis.ScaleView.ViewMinimum 
End Sub 
Cuestiones relacionadas