Генератор круговой диаграммы: генерирует неверный размер / угол ТОЛЬКО для некоторых значений - PullRequest
0 голосов
/ 10 января 2012

Я сделал очень простой генератор Pie Graph, используя Javascript и SVG графику. Вы просто вводите нужный угол на круговой диаграмме и затем нажимаете кнопку.

Моя проблема: Он генерирует графики, которые слишком велики для углов 100 градусов, 180 градусов и многих других. Он генерирует правильный круг для угла 277. Для угла, такого как 180, который должен быть полукругом, по некоторым причинам он показывает круг в 270 градусов.

Что не так с моим простым алгоритмом, который приводит к неправильным формам / значениям круговой диаграммы?

JSFiddle находится здесь (по какой-то причине JSFiddle не будет обновляться, но если вы скопируете приведенный ниже HTML, все будет работать) : http://jsfiddle.net/mabg3/1/

<html>
<head>
    <script type="text/javascript">
    <!--
function createPieGraph()
{
   var angle    = parseInt(document.getElementById("angleVal").value, 10);
   var path     = document.getElementById("pie"); //document.createElement("path");
   var diameter = 200
   var rad      = diameter/2;
   var point    = resolveToPoint(angle, diameter);
   var d        = "M"+diameter+","+diameter+" L"+point.mX+","+point.mY+" A"+rad+","+rad+" "+determineDisplayType(angle)+" "+determineArcEnd(angle, diameter, rad)+" z";
   path.setAttribute("d", d);
}

function resolveToPoint( /*int*/ deg, /*int*/ diameter ) 
{
   var rad  = Math.PI * deg / 180;
   var r    = diameter / 2;
   var x    = r * Math.cos(rad);
   var y    = r * Math.sin(rad);
   var midX = diameter;
   var midY = diameter;

   if (deg <= 90)
   {
      console.log("1");
      x = midX + x;
      y = midY - y;
   }
   else if (deg <= 180)
   {
      console.log("2");
      x = midX + x;
      y = midY + y;
   }
   else if (deg <= 270)
   {
      console.log("3");
      x = midX - x;
      y = midY + y;
   }
   else if (deg <= 360)
   {
      console.log("4");
      x = midX - x;
      y = Math.abs(y);
   }

   return {mX: x, mY: y};
}

function determineDisplayType( /*int*/ deg )
{
   if (deg <= 90)
      return "0 0,0";
   else if (deg <= 180)
      return "0 1,0";
   else if (deg <= 270)
      return "0 1,0";
   else if (deg <= 360)
      return "1 1,1";

   return "0 0,0";
}

function determineArcEnd( /*int*/ deg, /*int*/ diameter, /*int*/ rad )
{
   if (deg >= 270)
      return ""+rad+","+diameter;

   return ""+diameter+","+rad;
}
    -->
    </script>
</head> 
<body>

    <svg id="main" width="400" height="400" style="background-color: red;">
        <path id="pie" fill="blue" stroke="white"></path>
    </svg>

    <input type="text" id="angleVal" value="Enter angle"></input>
    <input type="button" onclick="createPieGraph();" value="Show Pie Graph"></input>
</body></html>

1 Ответ

0 голосов
/ 10 января 2012

http://jsfiddle.net/mabg3/11/

Во-первых, скрипка не сработала, потому что ваш javascript был упакован, но ваш встроенный обработчик кликов искал глобальную функцию. Я развернул его (см. Выпадающий список слева), что не очень хорошая идея для реального кода, но достаточно легко решает проблему в этом примере.

Я также сделал код намного короче. Не уверен, для чего предназначались все эти функции; единственный флаг, который нужно изменить, это large-arc, если угол больше половины окружности. Флаг sweep является постоянным, потому что мы всегда визуализируем в одной ориентации.

Мой код может быть легко улучшен и обобщен (вы можете обрабатывать отрицательные и> 360 углов по-разному, вы можете изменить начальный угол и т. Д.), Но он работает достаточно хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...