вторник, 10 сентября 2013 г.

Raphael Pie Chart Library

Файл index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style type="text/css">
        #canvas {
            width: 640px;
            height: 480px;
            margin: 0 auto;
            text-align: left;
            border: 1px solid #000000;
        }
    </style>
    <script data-main="js/index.js" src="js/lib/require/require.js"></script>
<title>Chart Lib</title>
</head>
<body>
    <div id="canvas"></div>
</body>
</html>

Файл index.js

require.config({
      paths: {
          jquery: 'lib/jquery/jquery'
        , raphael: 'lib/raphael/raphael'
        , raphaelPieChart: 'lib/raphael/raphael.piechart'
      }
    , shim: {
        raphaelPieChart: {
            deps: ['raphael']
        }
      }
});

require(
    [
          'jquery'
        , 'raphael'
        , 'raphaelPieChart'
    ]
    , function(
          $
        , Raphael
    ) {
        // Тестируем работу библиотеки Pie Chart.
        var paper = Raphael("canvas", 640, 480);
        paper.piechart(
              320, 240, 100
            , [25, 25, 25, 25]
            , {
                  colors: ['#cc0000', '#00ff00', '#000000', '#aa00aa']
                , labels: ['one', 'two', 'three', 'four']
                , labelsTextColor: '#ff0000'
              }
        );
    }
);

Файл raphael.piechart.js

// Библиотека Pie Chart.

// Параметры функции piechart(cx, cy, r, values, options):
// cx (number) - координата x центра круговой диаграммы.
// cy (number) - координата y вцентра круговой диаграммы.
// r (number) - радиус круговой диаграммы.
// values (array) - массив значений, по которым строится круговая диаграмма. Пример: [55, 20, 13, 32, 5, 1, 2].
// options (object) - список опций, использующихся для модификации круговой диаграммы.

// Возможные параметры options:
// options = {
//     stroke (string) - цвет линни окружности круговой диаграммы в формате "#ffffff".
//     strokeWidth (number) (по умолчанию равно 1) - толщина линии окружности круговой диаграммы.
//     colors (array) - массив цветов в формате "#ffffff", каждый из которых будет использоваться для закрашивания секторов круговой диаграмме.
//     labels (array) - массив, содержащий строки, которые будут использованы в качестве подписей к секторам круговой диаграммы.
// Ниже следующие опции будут работать, если опция labels была определена.
//     labelsTextColor (string) (по умолчанию равно "#000000") - цвет текста подписи в формате "#ffffff".
//     labelsMark (string) (по умолчанию равно "circle") - символ, используемый в качестве маркера слева от текста подписи. Данный символ имеет  тот же цвет, что и соответствующий сектор на круговой диаграмме.
//     labelsPosition (string) (по умолчанию равно "east") - место положения подписей рядом с круговой диаграммой. Для данной опции возможны следующие значения: "north", "south", "east", "west".
// }

// Пример использования библиотеки:
// paper.piechart(
//       320, 240, 100
//     , [25, 25, 25, 25]
//     , {
//            colors: ['#cc0000', '#00ff00', '#000000', '#aa00aa']
//          , labels: ['one', 'two', 'three', 'four']
//          , labelsTextColor: '#ff0000'
//       }
// );

;(function(){

    // Главная функция библиотеки.

    function PieChart (paper, cx, cy, r, values, options) {

        // Опции библиотеки.

        options = options || {};

        // Опции задающие цвета секторов и толщину разделительных линний на круговой диаграмме.
       
        var   stroke = options.stroke || "#ffffff"
            , strokeWidth = options.strokeWidth || 1
            , colors = options.colors || (function () {
                var   hues = [0.6, 0.2, 0.05, 0.1333, 0.75, 0]
                    , colors = []
                    , i;
                // Допустимо только 10 цветов. Для большего числа цветов необходимо изменить 10 и массив hues.
                for (i = 0; i < 10; i++) {
                    if (i < hues.length) {
                        colors.push('hsb(' + hues[i] + ', 0.75, 0.75)');
                    } else {
                        colors.push('hsb(' + hues[i - hues.length] + ', 1, 0.5)');
                    }
                }
                return colors;
              })();

        // Опции для отрисовки секторов круговой диаграммы

        var   len = values.length
            , total = 0
            , mangle
            , angle = 0
            , sectorPath
            , i;

        for (i = 0; i < len; i++) {
            total += values[i];
        }

        // Функция вычисления пути для отрисовки каждого сектора на круговой диаграмме.

        function sector(cx, cy, r, startAngle, endAngle) {
            var   rad = Math.PI / 180
                , x1 = cx + r * Math.cos(-startAngle * rad)
                , x2 = cx + r * Math.cos(-endAngle * rad)
                , y1 = cy + r * Math.sin(-startAngle * rad)
                , y2 = cy + r * Math.sin(-endAngle * rad)
                , path = [
                      'M', cx, cy // MoveTo: cx, cy
                    , 'L', x1, y1 // LineTo: x1, y1
                    , 'A', r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2 // Elliptical Arc: rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y
                    , 'z' // Close path
                ];
            return path.join();
        }

        // Цикл отрисовки секторов на круговой диаграмме.
       
        for (i = 0; i < len; i++) {
            mangle = angle - 360 * values[i] / total / 2;
            if (!i) {
                angle = 90 - mangle;
                mangle = angle - 360 * values[i] / total / 2;
            }
            sectorPath = sector(cx, cy, r, angle, angle -= 360 * values[i] / total);
            paper.path(sectorPath).attr({
                  'fill': colors[i]
                , 'stroke': stroke
                , 'stroke-width': strokeWidth
                , 'stroke-linejoin': 'round'
            });
        }

        // Опции задающие цвета, метки и положение подписей рядом с кгруговой диаграммой.

        var   labels = options.labels || values
            , labelsTextColor = options.labelsTextColor || '#000000'
            , labelsMark = options.labelsMark || 'circle'
            , labelsPosition = options.labelsPosition || 'east'
            , labelsSet = paper.set();

        labelsMark = labelsMark.toLowerCase();
        labelsPosition = labelsPosition.toLowerCase();

        // Цикл отрисовки подписей рядом с круговой диаграммой.
       
        var   x = cx + r + r / 5
            , y = cy
            , h = y + 10
            , labelMark
            , labelText;

        for (i = 0; i < len; i++) {
            labelMark = paper[labelsMark](x + 5, h, 5).attr({fill: colors[i], stroke: 'none'});
            labelText = paper.text(x + 20, h, labels[i]).attr({fill: labelsTextColor, 'text-anchor': 'start'});
            h += labelText.getBBox().height * 1.2;
            labelsSet.push(paper.set());
            labelsSet[i].push(labelMark).push(labelText);
        }

        var   labelsBoundingBox = labelsSet.getBBox()
            , translateToPosition = {
                  east: [0, -labelsBoundingBox.height / 2]
                , west: [-labelsBoundingBox.width - 2 * r - 20, -labelsBoundingBox.height / 2]
                , north: [-r - labelsBoundingBox.width / 2, -r - labelsBoundingBox.height - 10]
                , south: [-r - labelsBoundingBox.width / 2, r + 10]
              }[labelsPosition];
               
        labelsSet.translate.apply(labelsSet, translateToPosition);

    }

    // Добавляем библиотеку Pie Chart в состав библиотеки Raphael JS.

    Raphael.fn.piechart = function (cx, cy, r, values, options) {
        return new PieChart(this, cx, cy, r, values, options);
    };

})();

Комментариев нет:

Отправить комментарий