عنوان:

‫رسم نمودار توسط Kendo Chart


نویسنده: سیروان عفیفی
تاریخ: ۱۳۹۳/۱۱/۰۹ ۹:۳۵
آدرس: www.dntips.ir
پیشتر مطالبی در سایت، درباره KenoUI و همچنین ویجت‌های وب آن منتشر گردید. در این مطلب نگاهی خواهیم داشت بر تعدادی از ویجت‌های Kendo UI جهت رسم نمودار. توسط Kendo UI می‌توانیم نمودار‌های زیر را ترسیم کنیم:
  • Bar and Column
  • Line and Vertical Line
  • Area and Vertical Area
  • Bullet
  • Pie and Donut
  • Scatter
  • Scatter Line
  • Bubble
  • Radar and Polar

برای رسم نمودار می‌توانیم به صورت زیر عمل کنیم:

1- ابتدا باید استایل‌های مربوط به Data Visualization را به صفحه اضافه کنیم:

<link href="Content/kendo.dataviz.min.css" rel="stylesheet" />
<link href="Content/kendo.dataviz.default.min.css" rel="stylesheet" />
2- سپس یک عنصر را بر روی صفحه جهت نمایش نمودار، تعیین می‌کنیم:
<div id="chart"></div>
برای عنصر فوق می‌توانیم درون CSS و یا به صورت inline طول و عرضی را برای چارت تعیین کنیم:
<div id="chart" style="width: 400px; height: 600px"></div>
با فراخوانی تابع KendoChart، چارت بر روی صفحه نمایش داده می‌شود:
$("#chart").kendoChart();

همانطور که مشاهده می‌کنید هیچ داده‌ایی را هنوز برای چارت تعیین نکرده‌ایم؛ در نتیجه همانند تصویر فوق یک چارت خالی بر روی صفحه نمایش داده می‌شود. برای چارت فوق می‌توانیم خواصی از قبیل عنوان و ... را تعیین کنیم:
$("#chart").kendoChart({
    title: {
         text: "چارت آزمایشی"
    }
});

نمایش داده‌ها بر روی چارت:

داده‌ها را می‌توان هم به صورت local و هم به صورت remote دریافت و بر روی چارت نمایش داد. اینکار را می‌توانیم توسط قسمت series انجام دهیم:
$("#chart").kendoChart({
    title: {
         text: "عنوان چارت"
    },
    series: [
         { name: "داده‌های چارت", data: [200, 450, 300, 125] }
    ]
});
برای تعیین برچسب برای هر یک از داده‌ها نیز می‌توانیم خاصیت category axis را مقداردهی کنیم:
$("#chart").kendoChart({
                title: {
                    text: "عنوان چارت"
                },
                series: [
                     {
                         name: "داده‌های چارت",
                         data: [200, 450, 300, 125]
                     }
                ],
                categoryAxis: {
                    categories: [2000, 2001, 2002, 2003]
                }
            });

دریافت اطلاعات از سرور:
کدهای سمت سرور:
public class ProductsController : ApiController
    {
        public IEnumerable<ProductViewModel> Get()
        {
            var products = _productService.GetAllProducts();
            var query = products.GroupBy(p => p.Name).Select(p => new ProductViewModel
            {
                Value = p.Key,
                Count = p.Count()
            });
            return query;
        }
    }

    public class ProductViewModel
    {
        public string Value { get; set; }
        public int Count { get; set; }
    }

سپس برای دریافت اطلاعات از سمت سرور باید DataSource مربوط به چارت را مقداردهی کنیم:
var productsDataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: "api/products",
                        dataType: "json",
                        contentType: 'application/json; charset=utf-8',
                        type: 'GET'
                    }
                },
                error: function (e) {
                    alert(e.errorThrown.stack);
                },
                pageSize: 5,
                sort: { field: "Id", dir: "desc" }
            });

            $("#chart").kendoChart({
                title: {
                    text: "عنوان چارت"
                },
                dataSource: productsDataSource,
                series: [
                    {
                        field: "Count",
                        categoryField: "Value",
                        aggregate: "sum"
                    }
                ]
            });
همانطور که مشاهده می‌کنید در این حالت باید برای سری، field و categoryField را مشخص کنیم.
موارد فوق را می‌توانیم به صورت یک افزونه نیز کپسوله کنیم.

کدهای افزونه jquery.ChartAjax:
(function($) {
    $.fn.ShowChart = function(options) {
        var defaults = {
            url: '/',
            text: 'نمودار دایره ایی',
            theme: 'blueOpal',
            font: '13px bbc-nassim-bold',
            legendPosition: 'left',
            seriesField: 'Count',
            seriesCategoryField: 'Value',
            titlePosition: 'top',
            chartWidth: 400,
            chartHeight: 400
        };
        var options = $.extend(defaults, options);
        return this.each(function() {
            var chartDataSource = new kendo.data.DataSource({
                transport: {
                    read: {
                        url: options.url,
                        dataType: "json",
                        contentType: 'application/json; charset=utf-8',
                        type: 'GET'
                    }
                },
                error: function (e) {
                    // handle error
                }
            });
            $(this).kendoChart({
                chartArea: {
                    height: options.chartHeight
                },
                theme: options.theme,
                title: {
                    text: options.text,
                    font: options.font,
                    position: options.titlePosition
                },
                legend: {
                    position: options.legendPosition,
                    labels: {
                        font: options.font
                    }
                },
                seriesDefaults: {
                    labels: {
                        visible: false,
                        format: "{0}%"
                    }
                },
                dataSource: chartDataSource,
                series: [
                    {
                        type: "pie",
                        field: options.seriesField,
                        categoryField: options.seriesCategoryField,
                        aggregate: "sum",
                    }
                ],
                tooltip: {
                    visible: true,
                    template: "${category}: ${value}",
                    font: options.font
                }
            });
            
        });
    };
})(jQuery);
برای افزونه فوق موارد زیر در نظر گرفته شده است:
chartArea : جهت تعیین طول و عرض چارت
theme : جهت تعیین قالب‌های از پیش‌تعریف شده:
  • Black
  • BlueOpal
  • Bootstrap
  • Default
  • Flat
  • HighContrast
  • Material
  • MaterialBlack
  • Metro
  • MetroBlack
  • Moonlight
  • Silver
  • Uniform

title : جهت تعیین عنوان چارت

legend : جهت تنظیم ویژگی‌های قسمت گروه‌بندی چارت

tooltip : جهت تنظیم ویژگی‌های مربوط به نمایش tooltip در هنگام hover بر روی چارت.

لازم به ذکر است در قسمت series می‌توانید نوع چارت را تعیین کنید.

نحوه استفاده از افزونه فوق:
$('#chart').ShowChart({
                        url: "/Report/ByUnit",
                        legendPosition: "bottom"
});


دریافت سورس مثال جاری (KendoChart.zip)

نظرات

  • شروین ایرانی در ۱۳۹۳/۱۱/۱۹ ۹:۴۵
    با سلام  و تشکر؛ اگر در قسمت پایین نمودار در Column  Chart، عنوان داده‌ها یا همان Key متنش طولانی بود چطوری میشه Direction آن را به حالت مایل یا کج تبدیل کرد تا خوانا بشه. مرسی

    • سیروان عفیفی در ۱۳۹۳/۱۱/۱۹ ۱۱:۱
      می‌تونید direction مربوط به div را تغییر بدید در این حالت به درستی نمایش داده میشه:
      <div id="chart" style="direction: ltr">
      </div>
      • شروین ایرانی در ۱۳۹۳/۱۱/۱۹ ۱۱:۲۴
        مرسی؛ اما منظور من اطلاعات زیر هر ستون که در عکس روی هم افتاده رو خدمتتون عرض کردم. یعنی نام‌های فارسی در قسمت Axis.
        • وحید نصیری در ۱۳۹۳/۱۱/۱۹ ۱۲:۳۳
          از خاصیت چرخش آن باید استفاده کنید:
          <div id="chart"></div>
          <script>
          $("#chart").kendoChart({
            series: [{
              data: [1, 2, 3]
            }],
            valueAxis: {
              notes: {
                label: {
                  rotation: 90
                },
                data: [{ value: 1 }]
              }
            }
          });
          </script>
          • شروین ایرانی در ۱۳۹۳/۱۱/۱۹ ۱۲:۴۹
            متشکرم. ولی در قالب مثال بالا در  فایل jquery.ChartAjax دقیقا کجاش باید نوشت تا کار بده؟
            • سیروان عفیفی در ۱۳۹۳/۱۱/۱۹ ۱۳:۱۵
              کاملاً مشخصه، با افزودن یک کاما خطوط فوق را اضافه کنید، مثلاً بعد از series و یا tooltip
              • شروین ایرانی در ۱۳۹۳/۱۱/۱۹ ۱۳:۲۳
                      tooltip:
                                    {
                                    visible: true,
                                    template: "${category}: ${value}",
                                    font: options.font
                                    },
                
                             
                                valueAxis: {
                                    notes: {
                                        label: {
                                            rotation: 45
                                        }
                                    }
                                },
                به این شکل تغییر دادم ولی در نوع Column نتوانست rotation را به 45 درجه تبدیل کنه. آیا کار دیگه‌ای باید انجام داد. مرسی.
                • وحید نصیری در ۱۳۹۳/۱۱/۲۰ ۱۵:۴۱
                  برای حالت ستونی این تنظیم را اضافه کنید:
                  categoryAxis: [{
                      labels: {
                          rotation: -45
                      }
                  }]
        • سیروان عفیفی در ۱۳۹۳/۱۱/۱۹ ۱۳:۱۸
          بله، با افزودن rotation می‌تونید اینکار رو انجام بدید، من فکر کردم منظورتون قسمت legend هست، چون فعلاً از RTL برای چارت پشتیبانی نمی‌شه باید برای نمایش درست legend جهت رو به ltr تغییر بدیم.
  • شروین ایرانی در ۱۳۹۳/۱۱/۱۹ ۱۱:۳۱
    با سلام؛ لطفا بحث Export گرفتن از نمودار را هم توضیح دهید.
    • وحید نصیری در ۱۳۹۳/۱۱/۱۹ ۱۲:۳۷
      امکان تهیه‌ی خروجی به صورت PDF، SVG و تصویر را دارد. کلمه‌ی export را در این صفحه جستجو کنید. یک مثال:
      <div id="chart"></div>
      <script>
        $("#chart").kendoChart({
            pdf: {
                fileName: "Products.pdf"
            },
            legend: {
                position: "bottom"
            },
            series: [
                { name: "Series 1", data: [1, 2, 3] },
                { name: "Series 2", data: [3, 4, 5] }
            ]
        });
      
        var chart = $("#chart").getKendoChart();
        chart.saveAsPDF();
      </script>
      • شروین ایرانی در ۱۳۹۳/۱۱/۲۱ ۸:۲۷
        با سلام؛ در مورد خروجی PDF و یا SVG در مثال فوق، در داخل فایل jquery.ChartAjax خروجی کار نمی‌ده. لطفا راهنمایی فرمایید.
        • وحید نصیری در ۱۳۹۳/۱۱/۲۱ ۱۲:۱۹
          این روش خروجی:
          var chart = $("#chart").data("kendoChart");
          chart.saveAsPDF();
          با نگارش 2014.3.1119 به بعد Kendo UI سازگار است.
          این فایل‌ها را از آدرس ذیل می‌توانید دریافت کنید:
          http://cdn.kendostatic.com/2014.3.1119/js/kendo.all.min.js
          
          http://cdn.kendostatic.com/2014.3.1119/styles/kendo.default.min.css
          http://cdn.kendostatic.com/2014.3.1119/styles/kendo.common.min.css
          http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.default.min.css
          http://cdn.kendostatic.com/2014.3.1119/styles/kendo.dataviz.min.css
    • وحید نصیری در ۱۳۹۳/۱۱/۱۹ ۱۲:۳۹
      ضمنا مستندات عمومی kendo ui در این مخزن کد ارسال شده‌است.
  • وحید نصیری در ۱۳۹۳/۱۱/۲۱ ۱۴:۳۳
    تکمیل شده‌ی مثال جاری را به همراه تغییر نوع نمودار در زمان اجرا و خروجی تصویری، از مخزن کد ذیل دریافت کنید:
    KendoUI10
    • امیر بختیاری در ۱۳۹۳/۱۱/۲۹ ۱۵:۴۲
      با سلام
      من خروجی که شما قرار دادید رو به همراه خروجی PDF می‌خواهم ولی در خروجی PDF مشکلی که وجود دارد بر عکس شدن متن‌های فارسی می‌باشد. خیلی هم سرچ کردم چیزی گیر نیاوردم ممنون میشم کمک کنید در این زمینه
      • وحید نصیری در ۱۳۹۳/۱۱/۲۹ ۲۰:۳۳
        در نگارش فعلی، راه حل رسمی ندارد. خروجی PDF آن از RTL پشتیبانی نمی‌کند.
        فقط نحوه‌ی تعریف فونت آن به صورت زیر است:
         kendo.pdf.defineFont({
        /*"Verdana": "/fonts/Verdana.ttf", // this is a URL
        "Verdana|Bold": "/fonts/Verdana_Bold.ttf",
        "Verdana|Bold|Italic": "/fonts/Verdana_Bold_Italic.ttf",
        "Verdana|Italic": "/fonts/Verdana_Italic.ttf"*/
        "Iranian Sans":"/fonts/irsans.ttf"
        });
        - این مساله را باید در انجمن آن مطرح کنید و درخواست دهید که bidi.js موزیلا را به این پروژه هم اضافه کنند. جهت تهیه فایل PDF فارسی، نیاز است چرخاندن حروف یا تولید Glyph mirrors صورت گیرد که فایل bidi.js این‌کار را می‌تواند انجام دهد.
      • وحید نصیری در ۱۳۹۳/۱۱/۲۹ ۲۰:۴۴
        در اینجا برای اضافه شدن پشتیبانی رسمی از تهیه خروجی PDF راست به چپ، رای دهید.
  • سعدی همتی در ۱۳۹۴/۰۱/۰۴ ۱۳:۵۳
    با سلام و تشکر
    من مشکل مرتب سازی فیلد‌های از نوع عددی (int) در Kendo Chart دارم. همانند شکل زیر


    کد‌های نوشته شده به شکل زیر هستند (Year از جنس عدد هست)

     $(document).ready(function () {
            //چارت 4
            $.ajax({
                type: 'POST',
                url: '@Url.Action("TierStatistics4", "Dashboard", new { area = "Tier" })', 
                dataType: 'json',
                data: { CostCenterId: $("#CostCenterId").val(), QueryIndex: $("#QueryIndex").val() },
                success: function (data) {
                    dataSource = new kendo.data.DataSource({
                        data: data,
                        group: {
                            field: "Series"
                        },
                        sort:
                            {
                                field: "Year",
                                dir: "desc"
                            }
                    });
                    $("#chart4").kendoChart({
                        title: {
                            text: "آمار تعداد/هزینه(ریال) تایر مصرفی شعب به تفکیک مراکز هزینه و ماه‌های سال",
                            font: "irsans",
                        },
                        dataSource: dataSource,
                        series: [{
                            type: "column",
                            field: "Value",
                            categoryField: "Year",
                            name: "#=  group.value  #",
                        }],
                        categoryAxis: {
    
                            font: "irsans",
                            labels: {
                                font: "irsans"
                            }
                        },
                        valueAxis:
                            {
                                labels: {
                                    font: "irsans",
                                    visible: true,
                                }
                            },
                        seriesDefaults: {
    
                            style: "smooth",
                            labels: {
                                position: "Bottom",
                                visible: false,
                                fromat: "{0:n0}",
                                font: "irsans",
                                font: "irsans",
                                format: "{0:n0}",
                            }
                        },
                        legend: {
                            position: "top",
                            labels: {
                                font: "irsans"
                            }
                        },
                        tooltip: {
                            visible: true,
                            format: "{0:n0}",
                            template: "#= series.name #: #= value #",
                            font: "irsans",
                        }
                    })
                },
                error: function (ex) {
                    alert('خطا در بازیابی اطلاعات' + ex);
                }
            });
            return false;
        });
    ضمنا ViewModel هم به صورت زیر می‌باشد
     public class DashoardViewModel : System.Object
        {
            public DashoardThirdViewModel()
            {
            }
            public string Series { get; set; }
            // **********
            public int Year { get; set; }
            //**********
            public long Value { get; set; }
            // **********
    
    
        }

    ممنون از راهنمائی تون.
    • وحید نصیری در ۱۳۹۴/۰۱/۰۴ ۱۴:۶
      - زمانیکه از kendo ui data source استفاده می‌کنید، نیازی به استفاده از ajax مربوط به jQuery نیست. چون خودش به صورت توکار قابلیت کار با منبع داده‌ی ریموت را به صورت ای‌جکسی دارد. نمونه‌اش در مثال مطلب جاری بکار رفته‌است. به تنظیمات قسمت transport آن دقت کنید.
      اطلاعات بیشتر: «کار با Kendo UI DataSource» قسمت «استفاده از منابع داده راه دور » و همچنین مثال آن
      - همچنین در قسمت تنظیمات kendo ui data source امکان تعریف نوع فیلدهای مورد استفاده هم وجود دارند. نمونه‌ی آن در مطلب « صفحه بندی، مرتب سازی و جستجوی پویای اطلاعات به کمک Kendo UI Grid» استفاده شده‌است. متن «تعیین نوع فیلد برای جستجوی پویا مهم است» را در آن جستجو کنید.  بدون تعیین نوع داده‌ها، همه‌ی اطلاعات، رشته‌ای پردازش می‌شوند.
      • سعدی همتی در ۱۳۹۴/۰۱/۰۶ ۲۲:۱
        ممنون از این که با حوصله پاسخ دادید راستش مواردی را که اشاره کردید را تست کردم ولی باز نتیجه نگرفتم نهایتا اضافه کردن کد زیر کاملا مشکل را برطرف کرد.
         dataBound: function (e) {
                                e.sender.options.categoryAxis.categories.sort();
                            }
        و این هم  چارت بعد از افزودن کد فوق 

  • حسین اکبرزاده در ۱۳۹۶/۰۳/۲۵ ۰:۳۷
    با سلام . آیا امکانش هست کندو چارت مثلا kendo chart line با تاریخ شمسی کار کنه ؟  چون وقتی که فرمت تاریخ میلادی میگیره وقتی یک سری گپ بین تاریخ‌ها وجود داشته باشه خودش برای اون‌ها بازه هایی میسازه که بدون مقدار هست که  اگه string یا int از تاریخ شمسی بهش پاس بدیم نمی‌تونه اون حالت رو برای ما ایجاد کنه و همه رو با بازه‌های یکسان در نظر میگیره .
    مثلا فرض کنید سال 91 و 92 رو داریم سال 93 رو نداریم و دوباره سال 94 و 95 رو داریم .
    اگه خود کندو چارت بتونه تاریخ شمسی بگیره فکر کنم مشکل حل بشه . آیا روش خاصی داره یا راه بهتری پیشنهاد میکنید؟