Pasta grafik oluşturma


14

Zorluk basit:

Birkaç giriş değerine dayalı bir pasta grafik oluşturun.

Girdi, pozitif sayılar, ondalık veya tamsayıların bir listesi olacak ve çıktı, girdi değerlerinin her birinin ayrı renklerle ve alanların her birinin dışında bir yüzde değerinin gösterildiği bir pasta grafik olacaktır.

Kurallar:

  • Renkler görsel olarak ayırt edilebilir olmalıdır (kesin renkler isteğe bağlıdır)
  • En az iki, en fazla 10 giriş değeri olacaktır
  • Çemberin yarıçapı aralık [100 300]pikselinde olmalıdır
    • Varsayılan çıktı bir [100, 300]piksel yarıçapı verdiği sürece vektör grafikleri iyi durumda
  • Yüzde değerleri tam sayı olmalıdır
    • Yüzde değerinin nereye yerleştirileceğini söyleyen kesin bir kural yoktur, ancak hangi alana ait olduğu kolayca görülmelidir
    • En yakın karakter ile dairenin dış kenarı arasındaki mesafe [5, 40]piksel aralığı içinde olmalıdır
    • Yazı tipi isteğe bağlıdır
  • Çizim her bölgeyi ayıran siyah çizgiler içerebilir veya içermeyebilir
  • Pasta grafikler oluşturmak için yapılan işlevlere (örneğin, MATLAB:, piePython: matplotlib.pyplot.pieve Mathematica :) PieChartizin verilmez.
  • Normal yuvarlama kuralları (eğer varsa yukarı (1.00, 0.5], aşağı ise (0.5, 0.00))
  • Bir dilimin yüzde değeri 0.5%, çıktıdan küçükse 0%. Dilim yine de grafiğe dahil edilmelidir.
  • Lütfen inceleme için araziler (veya bir tercüman bağlantısı) sağlayın. Sadece 10 giriş değeri olan grafiği göstermek yeterlidir (çok uzun cevaplardan kaçınmak için)

Örnekler

Lütfen aşağıdaki örnek değerleri kullanın. Bir kullanarak uygun bir biçime listeleri dönüştürebilir sayısal liste dönüştürücü , mesela bunu 27 bayt tane tarafından jimmy23013 .

x = [0.3, 1.2] 

resim açıklamasını buraya girin

x = [3, 6, 2, 10]

resim açıklamasını buraya girin

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

resim açıklamasını buraya girin


"Dairenin yarıçapı [100 300] piksel aralığında olmalıdır." Vektör grafiklere de izin veriliyor mu?
Martin Ender

@ MartinBüttner, evet. Programdan çıktı varsayılan olarak [100, 300] arasında olduğu sürece sorun değil. Bu yeterli bir cevap mı?
Stewie Griffin

R 0,5 ila 0 arasında yuvarlar. Bu bir sorun mu var?
Masclins

0.5Varsayılansa sıfıra yuvarlamak uygundur . Ancak 0.500011'e yuvarlanmalıdır.
Stewie Griffin

Yanıtlar:


12

Mathematica 186 183 164 bayt

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]]&

Daha fazla golf olabilir. Şu anda bir Graphicsnesne oluşturuyor . Test senaryoları:




7

JavaScript (ES6), 311 310 302 298 bayt

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``)}

@Neil yardımı ile bir bayt kaydedildi!

açıklama

Geçerli sayfanın HTML'sine bir miktar SVG yazar. Grafiği 135 x 150, yarıçapın merkez noktası ve merkezden 100pxbir yarıçapında metin ile oluşturur 135px.

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));


Sanırım kullanarak birkaç bayt tasarruf edebilirsiniz with(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150].
Neil

Hmm, with(Math)var solution = a=>vb . Yazmak zorunda kalabilirsiniz
Neil

Hmm, aslında kullanabilirim with. Sanırım son denediğimde katı modda olabilirdim ...
user81655

@Neil Anladım, teşekkürler. Yazarken biraz acele ettiğim için bu konuda yapılabilecek daha fazla golf olduğundan eminim.
user81655

Yalnızca 1 bayt mı kaydedildi? Sanırım bir başlangıç ​​...
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()

resim açıklamasını buraya girin

En büyük örnek listesi için sonuç:

resim açıklamasını buraya girin


Python 2'de Python 2'lerle eval(raw_input())eşdeğer değil input()mi?
kedi

@ kedi evet öyle!
dieter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.