Створіть кругову діаграму


14

Завдання проста:

Створіть кругову діаграму на основі ряду вхідних значень.

Вхід буде переліком позитивних чисел, десяткових чи цілих чисел, а вихід буде круговою діаграмою, де кожне з вхідних значень представлене окремими кольорами, а відсоткове значення поза кожною з областей.

Правила:

  • Кольори мають бути візуально розрізненими (точні кольори необов’язково)
  • Буде щонайменше два та максимум 10 вхідних значень
  • Радіус кола повинен бути в [100 300]пікселях діапазону
    • Векторна графіка в порядку, поки вихідний за замовчуванням дає радіус [100, 300]пікселів
  • Значення відсотків повинні бути цілими числами
    • Не існує жодного суворого правила, де сказати, де слід розміщувати відсоткове значення, але повинно бути легко зрозуміти, до якої області він належить
    • Відстань між найближчим символом та зовнішнім краєм кола має бути в [5, 40]пікселях діапазону
    • Шрифт необов’язковий
  • Ділянка може мати або не мати чорних ліній, що розділяють кожну область
  • Функції, створені для створення кругових діаграм, наприклад, MATLAB:, piePython: matplotlib.pyplot.pieі Mathematica: PieChartне дозволяються
  • Нормальні правила округлення (вгору, якщо це так (1.00, 0.5], вниз, якщо є (0.5, 0.00))
  • Якщо значення відсоткового фрагмента менше 0.5%, виведіть 0%. Фрагмент все ж повинен бути включений до сюжету.
  • Надайте сюжети для експертизи (або посилання на перекладача). Досить показати лише графік з 10 вхідними значеннями (щоб уникнути дуже довгих відповідей)

Приклади

Будь ласка, використовуйте наведені нижче приклади. Ви можете перетворити списки у відповідний формат, використовуючи числовий перетворювач списку , наприклад, цей 27-байтний за допомогою jimmy23013 .

x = [0.3, 1.2] 

введіть тут опис зображення

x = [3, 6, 2, 10]

введіть тут опис зображення

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

введіть тут опис зображення


"Радіус кола повинен бути в діапазоні [100 300] пікселів." Чи дозволена також векторна графіка?
Мартін Ендер

@ MartinBüttner, так. Це нормально, доки вихід з програми виглядає так, що він за замовчуванням знаходиться між [100, 300]. Це достатня відповідь?
Стюі Гріффін

R обходить 0,5 до 0. Це проблема?
Masclins

Добре округляти 0.5до нуля, якщо це за замовчуванням. Але 0.50001треба округнути до 1.
Стюі Гріффін

Відповіді:


12

Математика, 186 183 164 байт

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

Можна було б пограти в гольф далі. В даний час генерує Graphicsоб’єкт. Тестові приклади:




7

JavaScript (ES6), 311 310 302 298 байт

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!

Пояснення

Записує деякі SVG в HTML поточної сторінки. Побудовує діаграму з центральною точкою 135 x 150радіуса 100pxта текстом у радіусі 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));


Я думаю, ви можете зберегти кілька байтів, використовуючи with(Math)c=r=>[sin(d=PI*2*(v+p))*r+135,cos(d)*r+150].
Ніл

Гм, можливо, вам доведеться писати with(Math)var solution = a=>і т. Д.
Ніл

Хм, насправді я можу використовувати with. Я думаю, що, можливо, я був у суворому режимі, коли я спробував це останній раз ...
user81655

@Neil Помітив там, спасибі Я впевнений, що на цьому можна зробити трохи більше гольфу, оскільки я трохи поспішав, коли писав це.
користувач81655

Збережено лише 1 байт? Я думаю, це початок ...
Ніл

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

введіть тут опис зображення

Результат для найбільшого прикладу:

введіть тут опис зображення


У Python 2 не є eval(raw_input())рівнозначним Python 2 input()?
кіт

@cat так це!
dieter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.