Advertisement
codemonkey

c3js-chart-widget.js

May 9th, 2016
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Generated by CoffeeScript 1.10.0
  2. (function() {
  3.   var BLOCK_HEIGHT, LineChartWidget,
  4.     bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  5.     indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
  6.  
  7.   BLOCK_HEIGHT = 62;
  8.  
  9.   freeboard.loadWidgetPlugin({
  10.     "type_name": "line_chart",
  11.     "display_name": "Line Chart",
  12.     "description": "Line Chart widget powered by C3.js, " + "written by Tomas Sandven",
  13.     "external_scripts": ["https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js", "https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"],
  14.     "fill_size": true,
  15.     "settings": [
  16.       {
  17.         name: "height",
  18.         display_name: "Height (in blocks)",
  19.         type: "number",
  20.         default_value: 5
  21.       }, {
  22.         name: "columns",
  23.         display_name: "Columns",
  24.         type: "calculated"
  25.       }, {
  26.         name: "flow",
  27.         display_name: "Flow data",
  28.         type: "boolean",
  29.         "default": false,
  30.         description: "Displays a neat animation when data flows from right to left.\nOnly set this to true if past data never changes."
  31.       }, {
  32.         name: "chart_type",
  33.         display_name: "Chart type",
  34.         type: "option",
  35.         default_value: "area",
  36.         options: [
  37.           {
  38.             name: "Area chart",
  39.             value: "area"
  40.           }, {
  41.             name: "Bar chart",
  42.             value: "bar"
  43.           }, {
  44.             name: "Line chart",
  45.             value: "line"
  46.           }, {
  47.             name: "Pie chart",
  48.             value: "pie"
  49.           }, {
  50.             name: "Donut chart",
  51.             value: "donut"
  52.           }
  53.         ]
  54.       }, {
  55.         name: "legend_position",
  56.         display_name: "Legend position",
  57.         type: "option",
  58.         default_value: "bottom",
  59.         options: [
  60.           {
  61.             name: "Bottom",
  62.             value: "bottom"
  63.           }, {
  64.             name: "Right",
  65.             value: "right"
  66.           }, {
  67.             name: "Inset",
  68.             value: "inset"
  69.           }
  70.         ]
  71.       }, {
  72.         name: "time_format",
  73.         display_name: "X Axis Time Format",
  74.         type: "text",
  75.         default_value: "%Y-%m-%d %H:%M:%S"
  76.       }, {
  77.         name: "display_markers",
  78.         display_name: "Display Time Markers",
  79.         type: "boolean"
  80.       }, {
  81.         name: "marker_interval",
  82.         display_name: "Time Markers: Interval",
  83.         type: "option",
  84.         options: [
  85.           {
  86.             name: "Every 30 seconds",
  87.             value: 30
  88.           }, {
  89.             name: "Every minute",
  90.             value: 60
  91.           }, {
  92.             name: "Every 10 minutes",
  93.             value: 60 * 10
  94.           }, {
  95.             name: "Every 30 minutes",
  96.             value: 60 * 30
  97.           }, {
  98.             name: "Every hour",
  99.             value: 60 * 60
  100.           }, {
  101.             name: "Every 2 hours",
  102.             value: 60 * 60 * 2
  103.           }, {
  104.             name: "Every 3 hours",
  105.             value: 60 * 60 * 3
  106.           }, {
  107.             name: "Every 4 hours",
  108.             value: 60 * 60 * 4
  109.           }, {
  110.             name: "Every 6 hours",
  111.             value: 60 * 60 * 6
  112.           }, {
  113.             name: "Every day",
  114.             value: 60 * 60 * 24
  115.           }, {
  116.             name: "Every 3 days",
  117.             value: 60 * 60 * 24 * 3
  118.           }
  119.         ]
  120.       }, {
  121.         name: "marker_time_format",
  122.         display_name: "Time Markers: Format",
  123.         type: "text",
  124.         default_value: "%Y-%m-%d %H:%M:%S"
  125.       }
  126.     ],
  127.     "newInstance": function(settings, newInstanceCallback) {
  128.       return newInstanceCallback(new LineChartWidget(settings));
  129.     }
  130.   });
  131.  
  132.   LineChartWidget = (function() {
  133.     function LineChartWidget(settings) {
  134.       this.onCalculatedValueChanged = bind(this.onCalculatedValueChanged, this);
  135.       this.onSettingsChanged = bind(this.onSettingsChanged, this);
  136.       this.getHeight = bind(this.getHeight, this);
  137.       this.render = bind(this.render, this);
  138.       this.displayLoading = bind(this.displayLoading, this);
  139.       this.updateTimeMarkers = bind(this.updateTimeMarkers, this);
  140.       this.flowChartData = bind(this.flowChartData, this);
  141.       this.updateChart = bind(this.updateChart, this);
  142.       this.createChart = bind(this.createChart, this);
  143.       this.setSettings = bind(this.setSettings, this);
  144.       this.setSettings(settings);
  145.     }
  146.  
  147.     LineChartWidget.prototype.setSettings = function(newSettings) {
  148.       var oldSettings, size;
  149.       oldSettings = this.settings;
  150.       this.settings = newSettings;
  151.       if (this.chart) {
  152.         size = {
  153.           width: this.chartElement.outerWidth(),
  154.           height: this.settings["height"] * BLOCK_HEIGHT
  155.         };
  156.         if (this.settings["size"] !== size) {
  157.           this.chart.resize(size);
  158.         }
  159.         if (oldSettings["chart_type"] !== newSettings["chart_type"]) {
  160.           this.chart.transform(this.settings["chart_type"]);
  161.         }
  162.         if (oldSettings["legend_position"] !== newSettings["legend_position"]) {
  163.           this.chart.destroy();
  164.           this.chart = this.createChart();
  165.         }
  166.       }
  167.       return this.updateTimeMarkers();
  168.     };
  169.  
  170.     LineChartWidget.prototype.createChart = function() {
  171.       var chart;
  172.       chart = c3.generate({
  173.         bindto: this.chartElement[0],
  174.         size: {
  175.           width: this.chartElement.outerWidth(),
  176.           height: Number(this.settings["height"]) * BLOCK_HEIGHT
  177.         },
  178.         data: {
  179.           type: this.settings["chart_type"],
  180.           x: "x",
  181.           xFormat: this.settings["time_format"],
  182.           columns: this.columns
  183.         },
  184.         axis: {
  185.           x: {
  186.             type: "timeseries",
  187.             show: false,
  188.             tick: {
  189.               format: "%Y-%m-%d %H:%M:%S",
  190.               culling: true,
  191.               fit: true,
  192.               rotate: 45
  193.             }
  194.           }
  195.         },
  196.         legend: {
  197.           position: this.settings["legend_position"]
  198.         },
  199.         interaction: {
  200.           enabled: false
  201.         },
  202.         transition: {
  203.           duration: 0
  204.         }
  205.       });
  206.       return chart;
  207.     };
  208.  
  209.     LineChartWidget.prototype.updateChart = function(oldColumns, newColumns) {
  210.       if (oldColumns === newColumns) {
  211.         return;
  212.       }
  213.       if (this.settings["flow"]) {
  214.         return this.flowChartData(oldColumns, newColumns);
  215.       } else {
  216.         return this.chart.load({
  217.           "columns": newColumns,
  218.           "unload": true
  219.         });
  220.       }
  221.     };
  222.  
  223.     LineChartWidget.prototype.flowChartData = function(oldColumns, newColumns) {
  224.       var additions, deleteCount, xColumn, xColumnOld;
  225.       additions = [];
  226.       $(newColumns).each(function(index, column) {
  227.         return additions.push(column.slice(0));
  228.       });
  229.       xColumn = newColumns[0];
  230.       xColumnOld = oldColumns[0];
  231.       deleteCount = xColumn.length - 1;
  232.       $(xColumn.slice(0).reverse()).each(function(index, value) {
  233.         if (index === xColumn.length - 1) {
  234.           return false;
  235.         }
  236.         if (indexOf.call(xColumnOld, value) < 0) {
  237.           deleteCount -= 1;
  238.         } else {
  239.           return false;
  240.         }
  241.         return null;
  242.       });
  243.       $(additions).each(function(index, value) {
  244.         return value.splice(1, deleteCount);
  245.       });
  246.       return this.chart.flow({
  247.         columns: additions
  248.       });
  249.     };
  250.  
  251.     LineChartWidget.prototype.updateTimeMarkers = function() {
  252.       var cursor, date, day, first, firstDate, firstMark, firstMarkDate, format, interval, last, lastDate, lastMark, lastMarkDate, marks, overflow, parse, tzOffset;
  253.       if (!this.chart) {
  254.         return;
  255.       }
  256.       if (!this.settings["display_markers"]) {
  257.         this.chart.xgrids.remove();
  258.         return;
  259.       }
  260.       parse = d3.time.format(this.settings["time_format"]).parse;
  261.       format = d3.time.format(this.settings["marker_time_format"]);
  262.       tzOffset = new Date().getTimezoneOffset() * 60;
  263.       firstDate = parse(this.columns[0][1]);
  264.       lastDate = parse(this.columns[0][this.columns[0].length - 1]);
  265.       first = firstDate.valueOf() / 1000;
  266.       last = lastDate.valueOf() / 1000;
  267.       interval = Number(this.settings["marker_interval"]);
  268.       overflow = first % interval;
  269.       firstMark = first - overflow;
  270.       firstMarkDate = new Date(firstMark * 1000);
  271.       overflow = (last + interval) % interval;
  272.       lastMark = (last + interval) - overflow;
  273.       lastMarkDate = new Date(lastMark * 1000);
  274.       marks = [];
  275.       day = 60 * 60 * 24;
  276.       cursor = firstMark - (firstMark % day);
  277.       while (true) {
  278.         if (cursor > lastMark) {
  279.           break;
  280.         }
  281.         if (cursor < firstMark) {
  282.           cursor += interval;
  283.           continue;
  284.         }
  285.         if (interval > 3600) {
  286.           date = new Date((cursor + tzOffset) * 1000);
  287.         } else {
  288.           date = new Date(cursor * 1000);
  289.         }
  290.         marks.push({
  291.           value: date,
  292.           text: format(date)
  293.         });
  294.         cursor += interval;
  295.       }
  296.       this.chart.xgrids(marks);
  297.       return null;
  298.     };
  299.  
  300.     LineChartWidget.prototype.displayLoading = function() {
  301.       var text, textContainer;
  302.       this.container.empty();
  303.       textContainer = $("<div>").css({
  304.         "display": "flex",
  305.         "height": this.settings["height"] * BLOCK_HEIGHT,
  306.         "justify-content": "center",
  307.         "align-items": "center",
  308.         "font-size": "2em"
  309.       }).appendTo(this.container);
  310.       return text = $("<div>").text("Loading data...").appendTo(textContainer);
  311.     };
  312.  
  313.     LineChartWidget.prototype.render = function(containerElement) {
  314.       if (containerElement) {
  315.         this.container = $(containerElement);
  316.       }
  317.       if (!this.columns) {
  318.         this.displayLoading();
  319.         return null;
  320.       }
  321.       if (!this.chart) {
  322.         this.container.empty();
  323.         this.chartElement = $("<div>");
  324.         this.container.append(this.chartElement);
  325.         this.chart = this.createChart();
  326.         this.updateTimeMarkers();
  327.       }
  328.       return null;
  329.     };
  330.  
  331.     LineChartWidget.prototype.getHeight = function() {
  332.       return this.settings["height"];
  333.     };
  334.  
  335.     LineChartWidget.prototype.onSettingsChanged = function(newSettings) {
  336.       this.setSettings(newSettings);
  337.       return null;
  338.     };
  339.  
  340.     LineChartWidget.prototype.onCalculatedValueChanged = function(settingName, newValue) {
  341.       var oldColumns;
  342.       if (settingName === "columns") {
  343.         oldColumns = this.columns;
  344.         this.columns = newValue;
  345.         if (!oldColumns) {
  346.           setTimeout(this.render, 1000);
  347.         } else {
  348.           this.updateChart(oldColumns, this.columns);
  349.         }
  350.       }
  351.       this.updateTimeMarkers();
  352.       return null;
  353.     };
  354.  
  355.     return LineChartWidget;
  356.  
  357.   })();
  358.  
  359. }).call(this);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement