تخفیف ویژه

آموزش رسم نمودار با Highcharts (جلسه 43) - نمودار حرارتی - قسمت 2

دسته بندی: جاوا اسکریپت
زمان مطالعه: 17 دقیقه
۰۵ تیر ۱۳۹۵

در این جلسه با ادامه موضوع مربوط به رسم نمودار با Highcharts در خدمتتون هستم. highcharts

نمونه دوم : نمودار حرارتی عظیم و بزرگ

در نمونه قبلی با یک نمودار حرارتی ساده شما رو آشنا کردیم و دیدید که چطور با استفاده از رنگها، داده‌ها رو نمایش دادیم و اونا رو با استفاده از نوار راهنمایی که در سمت راست اون قرار داشت در اختیار و معرض دید کاربران قرار دادیم. در این نمونه نمودار حرارتی رو خواهید دید که داده‌های زیادی رو در خودش جا میده و خیلی عظیم هست. کل کدهای مربوط به این نمونه رو در اختیارتون میزارم و بعد براتون توضیح میدم:

<html>

<head>
    <title>Highcharts Tutorial</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>
    <script src="http://code.highcharts.com/modules/data.js"></script>
    <script src="http://code.highcharts.com/modules/heatmap.js"></script>
</head>

<body>
    <div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
    <pre id="csv" style="display: none">Date,Time,Temperature
2013-01-01,0,1.3
2013-01-01,1,1.4
2013-01-01,2,1.6
...
...
...
2013-12-31,22,1.8
2013-12-31,23,1.6
</pre>
    <script language="JavaScript">
    $(document).ready(function() {
        (function(H) {
            var wrap = H.wrap,
                seriesTypes = H.seriesTypes;
            H.Series.prototype.getContext = function() {
                var canvas;
                if (!this.ctx) {
                    canvas = document.createElement('canvas');
                    canvas.setAttribute('width', this.chart.plotWidth);
                    canvas.setAttribute('height', this.chart.plotHeight);
                    canvas.style.position = 'absolute';
                    canvas.style.left = this.group.translateX + 'px';
                    canvas.style.top = this.group.translateY + 'px';
                    canvas.style.zIndex = 0;
                    canvas.style.cursor = 'crosshair';
                    this.chart.container.appendChild(canvas);
                    if (canvas.getContext) {
                        this.ctx = canvas.getContext('2d');
                    }
                }
                return this.ctx;
            }
            H.wrap(H.seriesTypes.heatmap.prototype, 'drawPoints', function(proceed) {

                var ctx;
                if (this.chart.renderer.forExport) {
                    proceed.call(this);

                } else {

                    if (ctx = this.getContext()) {
                        H.each(this.points, function(point) {
                            var plotY = point.plotY,
                                shapeArgs;

                            if (plotY !== undefined && !isNaN(plotY) && point.y !== null) {
                                shapeArgs = point.shapeArgs;

                                ctx.fillStyle = point.pointAttr[''].fill;
                                ctx.fillRect(shapeArgs.x, shapeArgs.y, shapeArgs.width, shapeArgs.height);
                            }
                        });

                    } else {
                        this.chart.showLoading("Your browser doesn't support HTML5 canvas, <br>please use a modern browser");
                    }
                }
            });
        }(Highcharts));

        var data = {
            csv: document.getElementById('csv').innerHTML,
            parsed: function() {
                start = +new Date();
            }
        };
        var chart = {
            type: 'heatmap',
            margin: [60, 10, 80, 50]
        };
        var title = {
            text: 'Highcharts extended heat map',
            align: 'left',
            x: 40
        };
        var subtitle = {
            text: 'Temperature variation by day and hour through 2013',
            align: 'left',
            x: 40
        };

        var xAxis = {
            type: 'datetime',
            min: Date.UTC(2013, 0, 1),
            max: Date.UTC(2014, 0, 1),
            labels: {
                align: 'left',
                x: 5,
                y: 14,
                format: '{value:%B}' // long month
            },
            showLastLabel: false,
            tickLength: 16
        };

        var yAxis = {
            title: {
                text: null
            },
            labels: {
                format: '{value}:00'
            },
            minPadding: 0,
            maxPadding: 0,
            startOnTick: false,
            endOnTick: false,
            tickPositions: [0, 6, 12, 18, 24],
            tickWidth: 1,
            min: 0,
            max: 23,
            reversed: true
        };

        var colorAxis = {
            stops: [
                [0, '#3060cf'],
                [0.5, '#fffbbc'],
                [0.9, '#c4463a'],
                [1, '#c4463a']
            ],
            min: -15,
            max: 25,
            startOnTick: false,
            endOnTick: false,
            labels: {
                format: '{value}?'
            }
        };

        var series = [{
            borderWidth: 0,
            nullColor: '#EFEFEF',
            colsize: 24 * 36e5, // one day
            tooltip: {
                headerFormat: 'Temperature<br/>',
                pointFormat: '{point.x:%e %b, %Y} {point.y}:00: <b>{point.value} ?</b>'
            },
            turboThreshold: Number.MAX_VALUE // #3404, remove after 4.0.5 release
        }];

        var json = {};
        json.chart = chart;
        json.data = data;
        json.title = title;
        json.xAxis = xAxis;
        json.yAxis = yAxis;
        json.colorAxis = colorAxis;
        json.series = series;

        $('#container').highcharts(json);
    });
    </script>
</body>

</html>

میبینید که علاوه بر فایل اصلی Highchart، فایلهای data.js و heatmap.js قرار داده شده است.

میبینید که در ابتدا کدی بصورت زیر قرار داده شده:

<pre id="csv" style="display: none">Date,Time,Temperature
2013-01-01,0,1.3
2013-01-01,1,1.4
2013-01-01,2,1.6
...
...
...
2013-12-31,22,1.8
2013-12-31,23,1.6
</pre>

با استفاده از کد بالا اومدیم و همه داده هایی که قراره در نمودار نمایش داده بشن رو وارد کردیم و اونا رو درون یک تگ pre قرار دادیم و display اون رو برابر با none در نظر گرفتیم تا در صفحه نمایش داده نشه. بدلیل اینکه اطلاعات زیاد بود نشد که همه داده‌ها رو در بالا قرار بدیم و بجای اونا ... قرار دادیم. کل داده‌ها در فایل زیر قرار داده شدن.

بعد از اون بعلت اینکه داده‌ها زیادن و باید المنتها و مربع‌های زیادی در نمودار ساخته شه، از SVG که خود نمودار تولید میکنه استفاده نمیکنیم و با استفاده از کد زیر اون رو در یک canvas نمایش میدیم و قابلیت‌های اون رو افزایش میدیم.

(function (H) {
    var wrap = H.wrap,
        seriesTypes = H.seriesTypes;
    H.Series.prototype.getContext = function () {
        var canvas;
        if (!this.ctx) {
            canvas = document.createElement('canvas');
            canvas.setAttribute('width', this.chart.plotWidth);
            canvas.setAttribute('height', this.chart.plotHeight);
            canvas.style.position = 'absolute';
            canvas.style.left = this.group.translateX + 'px';
            canvas.style.top = this.group.translateY + 'px';
            canvas.style.zIndex = 0;
            canvas.style.cursor = 'crosshair';
            this.chart.container.appendChild(canvas);
            if (canvas.getContext) {
                this.ctx = canvas.getContext('2d');
            }
        }
        return this.ctx;
    }
    H.wrap(H.seriesTypes.heatmap.prototype, 'drawPoints', function (proceed) {

        var ctx;
        if (this.chart.renderer.forExport) {
            proceed.call(this);

        } else {

            if (ctx = this.getContext()) {
                H.each(this.points, function (point) {
                    var plotY = point.plotY,
                        shapeArgs;

                    if (plotY !== undefined && !isNaN(plotY) && point.y !== null) {
                        shapeArgs = point.shapeArgs;

                        ctx.fillStyle = point.pointAttr[''].fill;
                        ctx.fillRect(shapeArgs.x, shapeArgs.y, shapeArgs.width, shapeArgs.height);
                    }
                });

            } else {
                this.chart.showLoading("Your browser doesn't support HTML5 canvas, <br>please use a modern browser");
            }
        }
    });
}(Highcharts));

با استفاده از کد بالا بجای اینکه از SVG برای رسم نمودار استفاده بشه، از canvas استفاده شده و اون رو برای این حالت بهینه‌تر کرده. کد بالا به نوعی افزونه یا plugin هست و قابلیتهای highcharts رو بالا برده.

var data = {
  csv: document.getElementById('csv').innerHTML,
  parsed: function () {
     start = +new Date();
  }
};

درون متغیر data هم داده‌های خودمون رو به نمودار معرفی کردیم. همون طور که میبینید درون ویژگی cdv، محتویات همون تگ pre رو قرار دادیم که در ابتدا تعریف کردیم.

var chart = {      
  type: 'heatmap',
  margin: [60, 10, 80, 50]
};

با استفاده از کد بالا نوع نمودار رو برابر با حرارتی قرار دادیم و فاصله نمودار رو از چهار طرف مشخص کردیم.

var xAxis = {
  type: 'datetime',
  min: Date.UTC(2013, 0, 1),
  max: Date.UTC(2014, 0, 1),
  labels: {
     align: 'left',
     x: 5,
     y: 14,
     format: '{value:%B}' // long month
  },
  showLastLabel: false,
  tickLength: 16
};

var yAxis = {
  title: {
     text: null
  },
  labels: {
     format: '{value}:00'
  },
  minPadding: 0,
  maxPadding: 0,
  startOnTick: false,
  endOnTick: false,
  tickPositions: [0, 6, 12, 18, 24],
  tickWidth: 1,
  min: 0,
  max: 23,
  reversed: true
};

با استفاده از کد بالا به ترتیب محورهای افقی و عمودی رو مشخص کردیم و ویژگی‌های مورد نظرمون رو براشون در نظر گرفتیم. محور افقی از نوع زمانی هست و حداقل اون ابتدای 2013 و حداکثر اون ابتدای 2014 هست. محور عمودی هم حداقل و حداکثر برابر با 0 تا 23 داره و بصورت معکوس یا reverse شده هست.

var colorAxis = {
  stops: [
     [0, '#3060cf'],
     [0.5, '#fffbbc'],
     [0.9, '#c4463a'],
     [1, '#c4463a']
  ],
  min: -15,
  max: 25,
  startOnTick: false,
  endOnTick: false,
  labels: {
     format: '{value}?'
  }
};

با استفاده از ویژگی بالا رنگ بندی اون محور راهنمایی که در پایین نمودار قرار داده شده رو مشخص میکنیم. میبینید که از 15- تا 25 گستردگی داره و همچنین رنگ 4 نقطه از اون رو مشخص کرده و بصورت گرادیانی نمایش داده شدن. خروجی بصورت زیر خواهد بود:heat largemap chart

امیدوارم از این مطلب خوشتون اومده باشه.

موفق و پیروز باشید

یا علی

Source

چه امتیازی به این مقاله می دید؟
نویسنده محمد اسفندیاری
بسیار به طراحی وب علاقمندم و به سرعت در حال یادگیری تمام مباحث پیشرفته هستم و دوست دارم که به دیگران هم یاد بدهم.

جلسات دوره

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

نیاز به لاگین

برای ارسال دیدگاه و یا پرسیدن سوال خود در این قسمت، باید در سایت لاگین شوید.