Google Charts asse verticale in numeri interi

Sto provando a configurare un istogramma di Google per visualizzare l’asse verticale in numeri interi, ma quando visualizza un numero piccolo come 1 visualizza anche 0,25, 0,50 ecc.

C’è comunque qualcosa per cambiare questo? Sono stato attraverso la documentazione e non riesco a trovare nulla che sembra rilevante.

Grazie

Risposta semplice: sì, ma è complicato.

Se vuoi solo che i numeri vengano visualizzati come numeri interi, allora è facile:

function drawVisualization() { // Create and populate the data table. var data = google.visualization.arrayToDataTable([ ['x', 'Cats', 'Blanket 1', 'Blanket 2'], ['A', 1, 1, 0.5], ['B', 2, 0.5, 1], ['C', 4, 1, 0.5], ['D', 8, 0.5, 1], ['E', 7, 1, 0.5], ['F', 7, 0.5, 1], ['G', 8, 1, 0.5], ['H', 4, 0.5, 1], ['I', 2, 1, 0.5], ['J', 3.5, 0.5, 1], ['K', 3, 1, 0.5], ['L', 3.5, 0.5, 1], ['M', 1, 1, 0.5], ['N', 1, 0.5, 1] ]); // Create and draw the visualization. new google.visualization.LineChart(document.getElementById('visualization')). draw(data, {curveType: "function", width: 500, height: 400, vAxis: {maxValue: 10, format: '0'}} ); } 

Se vai a Google Playground noterai che le etichette degli assi sono 0, 2.5, 5, 7.5, 10. Aggiungendo il formato: ‘0’ al vAxis, verranno visualizzati solo numeri interi, quindi le mie etichette diventano 0, 3 , 5, 8, 10. Ma ovviamente questo non è l’ideale dato che 8 display sono a metà strada tra 5 e 10, il che non lo è, perché il numero è in realtà 7.5 e viene arrotondato.

La tua capacità di cambiare la scala dell’asse / etichette è limitata. E per fare quello che stai chiedendo sarebbe necessario un po ‘di javascript per creare una scala e un numero di linee di griglia adeguate per evitare di rompere le cose in numeri funky.

Fondamentalmente, vuoi assicurarti che i tuoi valori massimi e minimi e il numero di griglie consentano una divisione facile in modo tale da ottenere solo numeri interi. Per fare ciò, è necessario creare una nuova logica funky. Ecco alcuni esempi di codice che ti consentiranno di ottenere un valore di asse min / max appropriato:

 // Take the Max/Min of all data values in all graphs var totalMax = 345; var totalMin = -123; // Figure out the largest number (positive or negative) var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin)); // Round to an exponent of 10 appropriate for the biggest number var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10); var roundingDec = Math.pow(10,roundingExp); // Round your max and min to the nearest exponent of 10 var newMax = Math.ceil(totalMax/roundingDec)*roundingDec; var newMin = Math.floor(totalMin/roundingDec)*roundingDec; // Determine the range of your values var range = newMax - newMin; // Define the number of gridlines (default 5) var gridlines = 5; // Determine an appropriate gap between gridlines var interval = range / (gridlines - 1); // Round that interval up to the exponent of 10 var newInterval = Math.ceil(interval/roundingDec)*roundingDec; // Re-round your max and min to the new interval var finalMax = Math.ceil(totalMax/newInterval)*newInterval; var finalMin = Math.floor(totalMin/newInterval)*newInterval; 

Ci sono un paio di problemi qui (sfortunatamente). Il primo è che sto usando il numero di gridlines per determinare i valori min / max – vuoi capire quante griglie dovresti avere per usare numeri interi carini. Il modo più semplice per farlo, credo, sarebbe il seguente (solo pseudo-codice):

 // Take the Max/Min of all data values in all graphs var totalMax = 3; var totalMin = -1; // Figure out the largest number (positive or negative) var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin)); // Round to an exponent of 10 appropriate for the biggest number var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10); var roundingDec = Math.pow(10,roundingExp); // Round your max and min to the nearest exponent of 10 var newMax = Math.ceil(totalMax/roundingDec)*roundingDec; var newMin = Math.floor(totalMin/roundingDec)*roundingDec; // Determine the range of your values var range = newMax - newMin; // Calculate the best factor for number of gridlines (2-5 gridlines) // If the range of numbers divided by 2 or 5 is a whole number, use it for (var i = 2; i <= 5; ++i) { if (Math.round(range/i) = range/i) { var gridlines = i } } 

Quindi imposta l'opzione delle griglie (vAxis.gridlines) sulla variabile sopra, e il tuo massimo su newMax e il tuo min to newMin. Questo dovrebbe darti etichette per numeri interi.

Nota: se i tuoi numeri sono veramente piccoli, la funzione sopra potrebbe non funzionare. Anche la funzione non è stata testata, quindi controlla alcuni esempi sul tuo tempo e fammi sapere se non funziona correttamente.

Solo per aggiungere alla risposta di jmac. Se si conosce il valore massimo del grafico, la soluzione è più semplice perché impostando il valore massimo è ansible assicurarsi che le linee della griglia visualizzino sempre lo stesso numero.

Se i tuoi contenuti sono molto dinamici, tuttavia la sua soluzione sembra essere l’unica.

Dopo aver lottato con lo stesso problema, sono arrivato a soluzioni molto semplici. Fai clic con il pulsante destro del mouse sul grafico, seleziona “Modifica avanzata” e:

1) Imposta la quantità di linee verticali per il grafico su “auto” (o manualmente uguale al numero di colonne di dati) – successivamente google non deve calcolare i breakpoint non interi. Ha fatto il trucco per me.

2) Oppure seleziona “Tratta le etichette come testo”, che le lascerà intatte.

Sto programmando in Java per generare i file html basati su dati dinamici e riutilizzando la class. Io uso un ArrayList () per entrambi i dati e la parte delle opzioni della generazione html di BarChart.

I miei dati vengono da me in un Multiset Guava che è inizializzato come TreeMultiset.

 Multiset items = TreeMultiset.create(); options = new ArrayList(); 

Devo assicurarmi che i miei articoli siano in ordine, quindi faccio una copia dell’elenco degli articoli.

 Multiset occurrences = Multisets.copyHighestCountFirst(items); 

Per ogni opzione che devo essere dyanmic, aggiungerò una stringa. Ad esempio, key è il titolo del mio grafico.

 options.add("\n title : '"+key+"'"); 

La prima cosa che faccio è ottenere il maggior numero di occorrenze nel Multiset ordinato.

 int max = occurrences.count(Iterables.get(occurrences, 0)); 

Poi voglio aggiungere un certo numero di zecche a hAxis. Ho circa una dozzina di set di dati. Quando i numeri massimi sono sotto i 100, sembra bello, ma quando i numeri sono centinaia o migliaia, allora devo filtrare la funzione “mod” in base al valore.

L’altro fastidio è che volevo almeno una riga oltre il valore più grande. Dovrò anche aggiustarlo.

Quindi aggiungendo la stringa nelle mie opzioni Array di stringhe:

 options.add("\n hAxis : { title : 'Count', ticks: <<"+ IntStream.range(0, max+5) .filter(x -> x % 4 == 0) .boxed() .collect(Collectors.toList()) +">> }"); 

IntStream genera tutti i numeri tra i valori. max + 5 consente un’ultima griglia alla destra della barra più lunga, ovvero una più grande della dimensione dell’intervallo. Il filtro mostra solo i numeri che possono essere modificati da 4, il mio intervallo che aggiusterò in seguito. .boxed () impedisce che i numeri interi vengano interpretati in modo errato per la stampa. .collect li avvolge semplicemente in un array di stringhe.

Posso quindi usare semplicemente options.toString () per stampare il forte, eccetto che, per la mia stampa, ho bisogno di togliere le parentesi dell’array della mia lista di opzioni, ma non le zecche. per esempio [e]. Se guardi sopra, è per questo che ho usato “<<" e ">>”.

  String optionstr = stripBrackets(options.toString()) .replaceAll("<<", "[") .replaceAll(">>", "]"); 

Il motivo per cui sto postando questa soluzione è che ti dà un grande controllo sull’etichettatura dell’asse reale. Oltre a rendere dinamico l’intervallo, che farò dopo, funziona abbastanza bene per tutti i miei set di dati.

Ecco l’html finale che è stato stampato. Non il parametro di spunta tra parentesi.