2010-09-17 11 views
14

Attualmente sto utilizzando la creazione di grafici all'interno di .NET utilizzando System.Windows.Forms.DataVisualization.Charting.Chart. Finora sembra molto potente e funziona alla grande. Tuttavia, vi è un enorme problema in termini di come si auto-calcola gli intervalli. Io uso molti valori double e in librerie come ZedGraph, gestisce perfettamente. Seleziona min/max/intervallo bene. Tuttavia, in MS Chart, è possibile selezionare 206.3334539832 come minimo e intervalli con una precisione decimale simile. Ovviamente questo sembra abbastanza brutto.Precisione auto-intervallo in MS Chart

Quindi, ho provato semplicemente a fare il formato dell'asse {0.00} e funziona benissimo quando carica il grafico. Tranne quando si esegue lo zoom in avanti, è necessaria una maggiore precisione, forse a 4 cifre decimali anziché a 2. Sembra che io sia bloccato con 9 posizioni decimali per tutto il tempo, oppure un numero fisso costante che può rompersi quando qualcuno richiede maggiore precisione. Preferisco che raccolga la precisione in base al livello di zoom attualmente applicato. Librerie come ZedGraph e Dundas (che credo utilizzi anche la MS!) Tendono a selezionare valori validi che cambiano man mano che si ingrandisce e rimpicciolisce.

C'è un modo per fare in modo che gli intervalli cambino di precisione mentre il riquadro dello zoom cambia? È probabilmente una proprietà semplice che ho impostato in modo errato, ma è difficile dire con milioni di proprietà questa cosa (specialmente quando ci sono circa 14 posizioni che rappresentano il concetto di intervallo).

+2

per quanto ne so, i controlli grafici si basano su controlli Dundas. Microsoft ha acquisito i componenti di visualizzazione dei dati di Dundas qualche tempo fa. Maggiori informazioni [qui] (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

Non ci sono immagini nella tua modifica? – noelicus

+0

@noelicus Scusa, nuovo lavoro da allora e quelle immagini sono state rimosse ad un certo punto (a quanto pare questo era prima che SO consentisse il caricamento delle immagini). Ho rimosso la modifica per ora. Guarderò e vedrò se riesco a trovare una copia di quelle immagini, e aggiorno questa domanda se posso. – drharris

risposta

5

Ho avuto lo stesso identico problema durante lo zoom. Ho aggiunto il codice per formattare le etichette degli assi e chiamarlo dal gestore Paint. Gli oggetti Vista asse hanno una proprietà IsZoomed e dispongono di funzioni per ottenere i limiti dell'asse corrente (GetViewMinimum/Maximum). Ho impostato Axis LabelStyle.Format su "N" per tutti i casi a meno che Max-Min = non sia inferiore a 1. Quindi ho impostato il formato su "F #" dove # è calcolato in base all'intervallo dell'asse.

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

Grazie mille per aver indicato GetViewMinimum/Maximum! Queste sono probabilmente le funzioni che stavo cercando. Proverò a farlo presto, e se funzionerà per il mio caso, reintegrerò la mia precedente taglia e te la consegnerò. Anche grazie per il codice per ottenere le cifre decimali - dopo alcuni test in WolframAlpha sembra che generi il numero perfetto di decimali. – drharris

+0

Ho dimenticato di riferire, ma alla fine ho avuto il tempo di spendere per implementare questo, e funziona PERFETTAMENTE. Continuo a pensare che il controllo stesso dovrebbe gestire questo tipo di logica (se i progetti open source come ZedGraph possono farlo, sicuramente MS/Dundas può farlo). Ho ripristinato la taglia originale su questa domanda poiché questo mi fa risparmiare un sacco di mal di testa da clienti infelici! Lo assegnerò non appena me lo consentirà. – drharris

1

Avendo giocato con il controllo grafico non sono stato in grado di trovare una soluzione semplice al problema. Tuttavia, quanto segue potrebbe aiutare:

Avete considerato di impostare da soli i valori massimo e minimo per gli assi? Se si arrotondano i valori massimi e minimi effettivi al numero "round" sensibile più vicino (5, 10, 0.5, 0.01), questo dovrebbe rendere gli intervalli calcolati un po 'più amichevoli.

Capisco che questa non è una soluzione ideale ma scegliendo con attenzione i valori massimo e/o minimo è possibile garantire che gli intervalli siano numeri "più belli". Se l'intervallo dei tuoi assi è dire divisibile per 2, 5 & 10 dovrebbe risultare in intervalli abbastanza buoni.

+0

Ho tentato di impostare me stesso min e max, ma questi grafici sono utilizzati per l'analisi e, non appena si esegue lo zoom in una regione personalizzata, si perdono i numeri rotondi e si torna a questo comportamento indesiderato. Inoltre, impostando il valore minimo su -10 a volte risulta in -10.00000023 o simile. Quindi sei a metà strada; risolve il display iniziale, ma con tutto lo zoom che accadrà, non è una soluzione completa al problema. Buono a sapersi non sono il solo, però! – drharris

0

Per fornire il risultato con un costo minimo si può utilizzare il formato scientifico esponenziale

+0

Se questa fosse una applicazione interna utilizzata solo da persone dalla mentalità scientifica, sarebbe fantastico! Tuttavia, disponiamo di una base di utenti che va dal professore universitario al coltivatore. Insegnare ad alcune di queste persone a leggere un formato esponenziale sarebbe quasi impossibile. Inoltre, l'uso di numeri scientifici non impedisce il problema di troppe posizioni decimali (come in 2.6666684583e-4) – drharris

+0

Basta usare string.Format ("{0: e2}", 123.456789). Prova anche a creare moduli di conversione personalizzati. – gabba

1

Perché non modificare stringa di formato numerico.

Crea stringa di formato

string formatString = "{0.00"; 

Identificare il livello di zoom, dicono zoomLevel = 2;

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

Ora utilizzare questo formato sulla legenda dell'asse. Utilizzare il generatore di stringhe o un modo migliore per modificare la stringa di formato.

+0

Il problema è che il "livello di zoom" ha poco significato. La scala non sarà sempre la stessa (a volte, l'asse X può variare da 100 a 120 e altre volte da 0 a 4000). Inoltre, l'utente può selezionare automaticamente una finestra di zoom, il che significa che non esiste un modo esplicito per determinare il numero di posizioni decimali da formattare. Buona risposta in teoria, ma non corrisponde al modello di oggetto qui. Codice – drharris

0

È possibile allegare a personalizzare l'evento. Da lì, è possibile modificare le etichette sulle ascisse:

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

set min. e max. valori:

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

ecc

0

è possibile aggiornare in modo dinamico il massimo e minimo in base al set di dati.ogni volta che l'utente esegue lo zoom, esegui un FOREACH su ogni punto e ottieni le statistiche e in base a tale set il tuo massimo e minimo

+0

? Come rilevare quando l'utente zooma? Come recuperare solo i punti che sono nella finestra mentre lo zoom è attivo? – drharris

0

aiuta a impostare l'IntervalOffset dell'asse, qui un esempio:

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