Crea un grafico a torta


14

La sfida è semplice:

Crea un grafico a torta basato su un numero di valori di input.

L'input sarà un elenco di numeri positivi, decimali o interi e l'output sarà un grafico a torta in cui ciascuno dei valori di input è rappresentato da colori separati e un valore percentuale al di fuori di ciascuna delle aree.

Regole:

  • I colori devono essere visivamente distinguibili (i colori esatti sono opzionali)
  • Ci saranno almeno due e massimo 10 valori di input
  • Il raggio del cerchio deve essere compreso nell'intervallo di [100 300]pixel
    • La grafica vettoriale è OK fintanto che l'output predefinito fornisce un raggio di [100, 300]pixel
  • I valori percentuali devono essere numeri interi
    • Non esiste una regola rigida che indichi dove deve essere posizionato il valore percentuale, ma deve essere facilmente visibile a quale area appartiene
    • La distanza tra il carattere più vicino e il bordo esterno del cerchio deve essere compresa nell'intervallo di [5, 40]pixel
    • Il carattere è facoltativo
  • La trama può avere o meno linee nere che separano ciascuna regione
  • Le funzioni create per la creazione di grafici a torta, ad esempio MATLAB:, piePython: matplotlib.pyplot.piee Mathematica: PieChartnon sono consentite
  • Regole di arrotondamento normali (su se è (1.00, 0.5], giù se è (0.5, 0.00))
  • Se il valore percentuale di una sezione è inferiore a 0.5%, output 0%. La sezione deve essere comunque inclusa nella trama.
  • Fornire grafici per l'esame (o un collegamento a un interprete). È sufficiente mostrare solo la trama con 10 valori di input (per evitare risposte molto lunghe)

Esempi

Si prega di utilizzare i valori di esempio di seguito. È possibile convertire gli elenchi in un formato appropriato utilizzando un convertitore di elenchi numerici , ad esempio questo da 27 byte di jimmy23013 .

x = [0.3, 1.2] 

inserisci qui la descrizione dell'immagine

x = [3, 6, 2, 10]

inserisci qui la descrizione dell'immagine

x = [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]

inserisci qui la descrizione dell'immagine


"Il raggio del cerchio deve essere compreso nell'intervallo [100 300] pixel." È consentita anche la grafica vettoriale?
Martin Ender,

@ MartinBüttner, sì. Va bene, fintanto che l'output del programma sembra essere compreso tra [100, 300] per impostazione predefinita. È una risposta sufficiente?
Stewie Griffin,

La R va da 0,5 a 0. È un problema?
Masclins,

Va bene arrotondare 0.5a zero se questo è predefinito. Ma 0.50001deve essere arrotondato a 1.
Stewie Griffin

Risposte:


12

Mathematica, 186 183 164 byte

Graphics[{Hue@#,Disk[{0,0},{1,1},a=2Pi{##}],Black,Text[ToString@Round[100(#2-#)]<>"%",5Through@{Cos,Sin}@Mean@a/4]}&@@@Partition[Accumulate[#/Tr@#]~Prepend~0,2,1]]&

Potrebbe essere ulteriormente giocato a golf. Attualmente genera un Graphicsoggetto. Casi test:




7

JavaScript (ES6), 311 310 302 298 byte

a=>{with(Math)document.write(`<svg height=300>`+a.map(n=>`<path fill=#${(p*4e3|0).toString(16)} d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]}Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],p=s=0,a.map(n=>s+=n)).join``)}

Ho salvato un byte con l'aiuto di @Neil!

Spiegazione

Scrive un po 'di SVG nell'HTML della pagina corrente. Crea il grafico con il punto centrale 135 x 150del raggio 100pxe il testo a un raggio di 135pxdal centro.

var solution =

a=>{
  with(Math)
  document.write(       // write to HTML body
    `<svg height=300>`+ // create 300px x 300px SVG canvas (width defaults to 300px)
    a.map(n=>           // for each number
      
      // Get the hex colour by multiplying the current position by (roughly) 0xfff
      `<path fill=#${(p*4e3|0).toString(16)
      
      // Calculate the path of the pie slice
      } d=M135,150L${c(o=100,v=0)}A${[o,o,0,(v=n/=s)+.5|0,0,c(o)]
      
      // Text
      }Z /><text x=${(z=c(135,v/=2))[0]} y=${z[p+=n,1]}>${n*o+.5|0}%</text>`,
      
      // Returns [ x, y ] for a certain radius at position v around the pie
      c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150],
      p=s=0,             // p = current position around pie (0 - 1)
      a.map(n=>s+=n)     // s = sum of all numbers
    ).join``
    
    +`</svg>` // <- this is just here for the test, so multiple charts can be displayed
  )
}

// Test
;[
  [0.3, 1.2],
  [3, 6, 2, 10],
  [0.4387, 0.3816, 0.7655, 0.7952, 0.1869, 0.4898, 0.4456, 0.6463, 0.7094, 0.7547]
].map(c=>solution(c));


Penso che puoi risparmiare qualche byte usando with(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150].
Neil,

Hmm, potresti dover scrivere with(Math)var solution = a=>ecc.
Neil,

Hmm, in realtà posso usare with. Penso che avrei potuto essere in modalità rigorosa quando l'ho provato l'ultima volta ...
user81655

@Neil Ce l'ho fatta, grazie. Sono abbastanza sicuro che ci sia un po 'più di golf che si può fare su questo, dato che stavo correndo un po' quando l'ho scritto.
user81655

Hai salvato solo 1 byte? Immagino sia un inizio ...
Neil,

6

Python + PIL, 365 355

from math import*;from random import*
from PIL import Image,ImageDraw
L,a,r=256,0,0.8;l,p,c=L/2,L/6,(L,L,L);I=Image.new('RGB',(L,L),c);D=ImageDraw.Draw(I)
x=input()
for i in x:b=a+ceil(360.0*i/sum(x));D.pieslice((p,p,L-p,L-p),int(a),int(b),tuple(map(randrange,c)));t=(a+b)*0.00872;D.text((l+cos(t)*l*r,l+sin(t)*l*r),str(int((b-a)/3.6))+'%',0);a=b
I.show()

inserisci qui la descrizione dell'immagine

Risultato per l'elenco di esempio più grande:

inserisci qui la descrizione dell'immagine


In Python 2, non è eval(raw_input())equivalente a Python 2 input()?
gatto

@cat si lo è!
Dieter,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.