~richardw/jarmon/ping-droprate-multiplier-846377

« back to all changes in this revision

Viewing changes to jarmon/jarmon.js

  • Committer: Richard Wall
  • Date: 2011-08-08 00:01:50 UTC
  • mfrom: (73.1.8 prerelease-fixes)
  • Revision ID: richard@largo-20110808000150-fc7wea24k7ky5x8l
Merge lp:~richardw/jarmon/prerelease-fixes
 * Add transformer function option to allow optional transformation of RRD values before they are plotted
 * Update dates of copyright notices
 * Remove DNS reports from example page
 * Remove unfinished editable graph controls - I will try and finish those off later.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * Copyright (c) 2010 Richard Wall <richard (at) the-moon.net>
 
2
 * Copyright (c) Richard Wall
3
3
 * See LICENSE for details.
4
4
 *
5
5
 * Wrappers and convenience fuctions for working with the javascriptRRD, jQuery,
337
337
 * @constructor
338
338
 * @param rrd {Object} A javascriptrrd.RRDFile
339
339
 * @param unit {String} The unit symbol for this data series
 
340
 * @param transformer {Function} A callable which performs a
 
341
 *      tranfsformation of the values returned from the RRD file.
340
342
 **/
341
 
jarmon.RrdQuery = function(rrd, unit) {
 
343
jarmon.RrdQuery = function(rrd, unit, transformer) {
342
344
    this.rrd = rrd;
343
345
    this.unit = unit;
 
346
    if(typeof(transformer) !== 'undefined') {
 
347
            this.transformer = transformer;
 
348
        } else {
 
349
            this.transformer = function(v) {return v;};
 
350
        }
344
351
};
345
352
 
346
353
jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs,
443
450
    var val;
444
451
    var timestamp = startRowTime;
445
452
    for(i=startRowIndex; i<endRowIndex; i++) {
446
 
        val = rra.getEl(i, dsIndex);
 
453
        val = this.transformer(rra.getEl(i, dsIndex));
447
454
        flotData.push([timestamp*1000.0, val]);
448
455
        timestamp += step;
449
456
    }
480
487
 * @param unit {String} The unit suffix of this data eg 'bit/sec'
481
488
 * @param downloader {Function} A callable which returns a Deferred and calls
482
489
 *      back with a javascriptrrd.BinaryFile when it has downloaded.
 
490
 * @param transformer {Function} A callable which performs a
 
491
 *      tranfsformation of the values returned from the RRD file.
483
492
 **/
484
 
jarmon.RrdQueryRemote = function(url, unit, downloader) {
 
493
jarmon.RrdQueryRemote = function(url, unit, downloader, transformer) {
485
494
    this.url = url;
486
495
    this.unit = unit;
487
 
    this.downloader = downloader || jarmon.downloadBinary;
 
496
    if(typeof(downloader) == 'undefined') {
 
497
        this.downloader = jarmon.downloadBinary;
 
498
    } else {
 
499
        this.downloader = downloader;
 
500
    }
 
501
    this.transformer = transformer;
 
502
 
488
503
    this.lastUpdate = 0;
489
504
    this._download = null;
490
505
};
657
672
            }
658
673
        }
659
674
 
660
 
        if(self.options.yaxis.tickDecimals !== null) {
 
675
        if(typeof(self.options.yaxis.tickDecimals) === 'number') {
661
676
            decimalPlaces = self.options.yaxis.tickDecimals;
662
677
        }
663
678
 
693
708
        }
694
709
        var label = recipe.data[j][2];
695
710
        var unit = recipe.data[j][3];
 
711
        var transformer = recipe.data[j][4];
696
712
 
697
713
        if(typeof(dataDict[rrd]) === 'undefined') {
698
714
            dataDict[rrd] = new jarmon.RrdQueryRemote(
699
 
                rrd, unit, this.downloader);
 
715
                rrd, unit, this.downloader, transformer);
700
716
        }
701
717
        this.addData(label, new jarmon.RrdQueryDsProxy(dataDict[rrd], ds));
702
718
    }
813
829
 
814
830
            var yaxisUnitLabel = $('<div>')
815
831
                .text(self.siPrefix + unit)
816
 
                .css({width: '100px',
817
 
                      position: 'absolute',
818
 
                      top: '80px',
819
 
                      left: '-90px',
 
832
                .css({'width': '100px',
 
833
                      'position': 'absolute',
 
834
                      'top': '80px',
 
835
                      'left': '-110px',
820
836
                      'text-align': 'right'});
821
837
            self.template.find('.chart').append(yaxisUnitLabel);
822
838
 
1178
1194
    this.placeholders = [];
1179
1195
 
1180
1196
    this.$tabBar = $('<ul/>', {'class': 'css-tabs'}).appendTo($tpl);
1181
 
 
1182
 
    // Icon and hidden input box for adding new tabs. See event handlers below.
1183
 
    this.$newTabControls = $('<li/>', {
1184
 
        'class': 'newTabControls',
1185
 
        'title': 'Add new tab'
1186
 
    }).append(
1187
 
        $('<img/>', {src: 'assets/icons/next.gif'}),
1188
 
        $('<input/>', {'type': 'text'}).hide()
1189
 
    ).appendTo(this.$tabBar);
1190
 
 
1191
1197
    this.$tabPanels = $('<div/>', {'class': 'css-panes charts'}).appendTo($tpl);
1192
1198
    var tabName, $tabPanel, placeNames;
1193
1199
    for(var i=0; i<recipe.length; i++) {
1203
1209
    }
1204
1210
 
1205
1211
    this.setup();
1206
 
 
1207
 
    // Show the new tab name input box when the user clicks the new tab icon
1208
 
    $('ul.css-tabs > li.newTabControls > img', $tpl[0]).live(
1209
 
        'click',
1210
 
        function(e) {
1211
 
            $(this).hide().siblings().show().focus();
1212
 
        }
1213
 
    );
1214
 
 
1215
 
    // When the "new" tab input loses focus, use its value to create a new
1216
 
    // tab.
1217
 
    // XXX: Due to event bubbling, this event seems to be triggered twice, but
1218
 
    // only when the input is forcefully blurred by the "keypress" event handler
1219
 
    // below. To prevent two tabs, we blank the input field value. Tried
1220
 
    // preventing event bubbling, but there seems to be some subtle difference
1221
 
    // with the use of jquery live event handlers.
1222
 
    $('ul.css-tabs > li.newTabControls > input', $tpl[0]).live(
1223
 
        'blur',
1224
 
        {self: this},
1225
 
        function(e) {
1226
 
            var self = e.data.self;
1227
 
            var value = this.value;
1228
 
            this.value = '';
1229
 
            $(this).hide().siblings().show();
1230
 
            if(value) {
1231
 
                self.newTab(value);
1232
 
                self.setup();
1233
 
                self.$tabBar.data("tabs").click(value);
1234
 
            }
1235
 
        }
1236
 
    );
1237
 
 
1238
 
    // Unfocus the input element when return key is pressed. Triggers a
1239
 
    // blur event which then replaces the input with a tab
1240
 
    $('ul.css-tabs > li > input', $tpl[0]).live(
1241
 
        'keypress',
1242
 
        function(e) {
1243
 
            if(e.which === 13) {
1244
 
                $(this).blur();
1245
 
            }
1246
 
        }
1247
 
    );
1248
 
 
1249
 
    // Show tab name input box when tab is double clicked.
1250
 
    $('ul.css-tabs > li > a', $tpl[0]).live(
1251
 
        'dblclick',
1252
 
        {self: this},
1253
 
        function(e) {
1254
 
            var $originalLink = $(this);
1255
 
            var $input = $('<input/>', {
1256
 
                'value': $originalLink.text(),
1257
 
                'name': 'editTabTitle',
1258
 
                'type': 'text'
1259
 
            });
1260
 
            $originalLink.replaceWith($input);
1261
 
            $input.focus();
1262
 
        }
1263
 
    );
1264
 
 
1265
 
    // Handle the updating of the tab when its name is edited.
1266
 
    $('ul.css-tabs > li > input[name=editTabTitle]', $tpl[0]).live(
1267
 
        'blur',
1268
 
        {self: this},
1269
 
        function(e) {
1270
 
            var self = e.data.self;
1271
 
            $(this).replaceWith(
1272
 
                $('<a/>', {
1273
 
                    href: ['#', this.value].join('')
1274
 
                }).text(this.value)
1275
 
            );
1276
 
            self.setup();
1277
 
            self.$tabBar.data("tabs").click(this.value);
1278
 
        }
1279
 
    );
1280
 
 
1281
 
    $('input[name=add_new_chart]', $tpl[0]).live(
1282
 
        'click',
1283
 
        {self: this},
1284
 
        function(e) {
1285
 
            console.log(e);
1286
 
        }
1287
 
    );
1288
1212
};
1289
1213
 
1290
1214
jarmon.TabbedInterface.prototype.newTab = function(tabName) {
1294
1218
    ).appendTo(this.$tabBar);
1295
1219
    var $placeholder = $('<div/>');
1296
1220
    // Add tab panel
1297
 
    $('<div/>').append(
1298
 
        $placeholder,
1299
 
        $('<div/>', {'class': 'tab-controls'}).append(
1300
 
            $('<input/>', {
1301
 
                type: 'button',
1302
 
                value: 'Add new chart',
1303
 
                name: 'add_new_chart'
1304
 
            })
1305
 
        )
1306
 
    ).appendTo(this.$tabPanels);
 
1221
    $('<div/>').append($placeholder).appendTo(this.$tabPanels);
1307
1222
 
1308
1223
    return $placeholder;
1309
1224
};
1310
1225
 
1311
1226
jarmon.TabbedInterface.prototype.setup = function() {
1312
 
    this.$newTabControls.remove();
1313
1227
    // Destroy then re-initialise the jquerytools tabs plugin
1314
1228
    var api = this.$tabBar.data("tabs");
1315
1229
    if(api) {
1316
1230
        api.destroy();
1317
1231
    }
1318
1232
    this.$tabBar.tabs(this.$tabPanels.children('div'));
1319
 
    this.$newTabControls.appendTo(this.$tabBar);
1320
1233
};
1321
1234
 
1322
1235