From de22ad3cba1b44fe5f77c26a802ef394f39f9852 Mon Sep 17 00:00:00 2001 From: eki1503 Date: Fri, 1 Apr 2022 07:58:47 +0200 Subject: [PATCH 1/3] Update widget_chart.js --- www/tablet/js/widget_chart.js | 1865 ++++++--------------------------- 1 file changed, 334 insertions(+), 1531 deletions(-) diff --git a/www/tablet/js/widget_chart.js b/www/tablet/js/widget_chart.js index 706d0b01..df0a05ad 100644 --- a/www/tablet/js/widget_chart.js +++ b/www/tablet/js/widget_chart.js @@ -2,8 +2,8 @@ * Copyright (c) 2015-2017 Kurt Eckert * Under MIT License (http://www.opensource.org/licenses/mit-license.php) */ -/* Version 2.11.0 -/* Compatible FTUI Version >= 2.7.2 +/* Version 2.7 +/* Compatible FTUI Version >= 2.6 /* global ftui:true, Modul_widget:true, Powerange:true */ @@ -96,26 +96,14 @@ function depends_chart (){ })(); } - if (!String.stripFormat) { - String.prototype.stripFormat = function() { - return this.replace(/\<(i|b|em|small|strong|mark|del|ins|sub|sup|class)\>/,'').replace(/\<\/(i|b|em|small|strong|mark|del|ins|sub|sup|class)\>/,''); - }; - } - if (!$.fn.HTML2SVG) { $.fn.HTML2SVG = function(text,delfirst) { - var isIE = navigator.userAgent.match(/Trident/); this.each(function() { var convertedText = widget_chart.getFormattedText(text); - if (convertedText.search(/^\'; - var elem = $(this); - if (delfirst) elem.empty(); - if (isIE) { - convertedText = convertedText.replace(/\]*\>/g,'').replace(/\<\/tspan\>/g,''); - elem.text(convertedText); - } else { - elem.html(convertedText); - } + if (convertedText.search(/tspan/) < 0) convertedText = '' + convertedText + ''; + var elem = this; + if (delfirst) $(elem).empty(); + $(elem).html(convertedText); }); }; } @@ -202,7 +190,6 @@ var widget_chart = { initialized : [], LOGTYPE : 'console', logtext : '', - gBCaps : undefined, doLog: function(func,info,level) { // print log commands to console if DEBUG is set if (widget_chart.LOGTYPE == 'console') { @@ -241,11 +228,10 @@ var widget_chart = { return isIE; }, fontNameToUnicode: function(name) { - var FONT_AWESOME = {"fa-500px":"\uf26e","fa-adjust":"\uf042","fa-adn":"\uf170","fa-align-center":"\uf037","fa-align-justify":"\uf039","fa-align-left":"\uf036","fa-align-right":"\uf038","fa-amazon":"\uf270","fa-ambulance":"\uf0f9","fa-anchor":"\uf13d","fa-android":"\uf17b","fa-angellist":"\uf209","fa-angle-double-down":"\uf103","fa-angle-double-left":"\uf100","fa-angle-double-right":"\uf101","fa-angle-double-up":"\uf102","fa-angle-down":"\uf107","fa-angle-left":"\uf104","fa-angle-right":"\uf105","fa-angle-up":"\uf106","fa-apple":"\uf179","fa-archive":"\uf187","fa-area-chart":"\uf1fe","fa-arrow-circle-down":"\uf0ab","fa-arrow-circle-left":"\uf0a8","fa-arrow-circle-o-down":"\uf01a","fa-arrow-circle-o-left":"\uf190","fa-arrow-circle-o-right":"\uf18e","fa-arrow-circle-o-up":"\uf01b","fa-arrow-circle-right":"\uf0a9","fa-arrow-circle-up":"\uf0aa","fa-arrow-down":"\uf063","fa-arrow-left":"\uf060","fa-arrow-right":"\uf061","fa-arrow-up":"\uf062","fa-arrows":"\uf047","fa-arrows-alt":"\uf0b2","fa-arrows-h":"\uf07e","fa-arrows-v":"\uf07d","fa-asterisk":"\uf069","fa-at":"\uf1fa","fa-automobile":"\uf1b9","fa-backward":"\uf04a","fa-balance-scale":"\uf24e","fa-ban":"\uf05e","fa-bank":"\uf19c","fa-bar-chart":"\uf080","fa-bar-chart-o":"\uf080","fa-barcode":"\uf02a","fa-bars":"\uf0c9","fa-battery-0":"\uf244","fa-battery-1":"\uf243","fa-battery-2":"\uf242","fa-battery-3":"\uf241","fa-battery-4":"\uf240","fa-battery-empty":"\uf244","fa-battery-full":"\uf240","fa-battery-half":"\uf242","fa-battery-quarter":"\uf243","fa-battery-three-quarters":"\uf241","fa-bed":"\uf236","fa-beer":"\uf0fc","fa-behance":"\uf1b4","fa-behance-square":"\uf1b5","fa-bell":"\uf0f3","fa-bell-o":"\uf0a2","fa-bell-slash":"\uf1f6","fa-bell-slash-o":"\uf1f7","fa-bicycle":"\uf206","fa-binoculars":"\uf1e5","fa-birthday-cake":"\uf1fd","fa-bitbucket":"\uf171","fa-bitbucket-square":"\uf172","fa-bitcoin":"\uf15a","fa-black-tie":"\uf27e","fa-bold":"\uf032","fa-bolt":"\uf0e7","fa-bomb":"\uf1e2","fa-book":"\uf02d","fa-bookmark":"\uf02e","fa-bookmark-o":"\uf097","fa-briefcase":"\uf0b1","fa-btc":"\uf15a","fa-bug":"\uf188","fa-building":"\uf1ad","fa-building-o":"\uf0f7","fa-bullhorn":"\uf0a1","fa-bullseye":"\uf140","fa-bus":"\uf207","fa-buysellads":"\uf20d","fa-cab":"\uf1ba","fa-calculator":"\uf1ec","fa-calendar":"\uf073","fa-calendar-check-o":"\uf274","fa-calendar-minus-o":"\uf272","fa-calendar-o":"\uf133","fa-calendar-plus-o":"\uf271","fa-calendar-times-o":"\uf273","fa-camera":"\uf030","fa-camera-retro":"\uf083","fa-car":"\uf1b9","fa-caret-down":"\uf0d7","fa-caret-left":"\uf0d9","fa-caret-right":"\uf0da","fa-caret-square-o-down":"\uf150","fa-caret-square-o-left":"\uf191","fa-caret-square-o-right":"\uf152","fa-caret-square-o-up":"\uf151","fa-caret-up":"\uf0d8","fa-cart-arrow-down":"\uf218","fa-cart-plus":"\uf217","fa-cc":"\uf20a","fa-cc-amex":"\uf1f3","fa-cc-diners-club":"\uf24c","fa-cc-discover":"\uf1f2","fa-cc-jcb":"\uf24b","fa-cc-mastercard":"\uf1f1","fa-cc-paypal":"\uf1f4","fa-cc-stripe":"\uf1f5","fa-cc-visa":"\uf1f0","fa-certificate":"\uf0a3","fa-chain":"\uf0c1","fa-chain-broken":"\uf127","fa-check":"\uf00c","fa-check-circle":"\uf058","fa-check-circle-o":"\uf05d","fa-check-square":"\uf14a","fa-check-square-o":"\uf046","fa-chevron-circle-down":"\uf13a","fa-chevron-circle-left":"\uf137","fa-chevron-circle-right":"\uf138","fa-chevron-circle-up":"\uf139","fa-chevron-down":"\uf078","fa-chevron-left":"\uf053","fa-chevron-right":"\uf054","fa-chevron-up":"\uf077","fa-child":"\uf1ae","fa-chrome":"\uf268","fa-circle":"\uf111","fa-circle-o":"\uf10c","fa-circle-o-notch":"\uf1ce","fa-circle-thin":"\uf1db","fa-clipboard":"\uf0ea","fa-clock-o":"\uf017","fa-clone":"\uf24d","fa-close":"\uf00d","fa-cloud":"\uf0c2","fa-cloud-download":"\uf0ed","fa-cloud-upload":"\uf0ee","fa-cny":"\uf157","fa-code":"\uf121","fa-code-fork":"\uf126","fa-codepen":"\uf1cb","fa-coffee":"\uf0f4","fa-cog":"\uf013","fa-cogs":"\uf085","fa-columns":"\uf0db","fa-comment":"\uf075","fa-comment-o":"\uf0e5","fa-commenting":"\uf27a","fa-commenting-o":"\uf27b","fa-comments":"\uf086","fa-comments-o":"\uf0e6","fa-compass":"\uf14e","fa-compress":"\uf066","fa-connectdevelop":"\uf20e","fa-contao":"\uf26d","fa-copy":"\uf0c5","fa-copyright":"\uf1f9","fa-creative-commons":"\uf25e","fa-credit-card":"\uf09d","fa-crop":"\uf125","fa-crosshairs":"\uf05b","fa-css3":"\uf13c","fa-cube":"\uf1b2","fa-cubes":"\uf1b3","fa-cut":"\uf0c4","fa-cutlery":"\uf0f5","fa-dashboard":"\uf0e4","fa-dashcube":"\uf210","fa-database":"\uf1c0","fa-dedent":"\uf03b","fa-delicious":"\uf1a5","fa-desktop":"\uf108","fa-deviantart":"\uf1bd","fa-diamond":"\uf219","fa-digg":"\uf1a6","fa-dollar":"\uf155","fa-dot-circle-o":"\uf192","fa-download":"\uf019","fa-dribbble":"\uf17d","fa-dropbox":"\uf16b","fa-drupal":"\uf1a9","fa-edit":"\uf044","fa-eject":"\uf052","fa-ellipsis-h":"\uf141","fa-ellipsis-v":"\uf142","fa-empire":"\uf1d1","fa-envelope":"\uf0e0","fa-envelope-o":"\uf003","fa-envelope-square":"\uf199","fa-eraser":"\uf12d","fa-eur":"\uf153","fa-euro":"\uf153","fa-exchange":"\uf0ec","fa-exclamation":"\uf12a","fa-exclamation-circle":"\uf06a","fa-exclamation-triangle":"\uf071","fa-expand":"\uf065","fa-expeditedssl":"\uf23e","fa-external-link":"\uf08e","fa-external-link-square":"\uf14c","fa-eye":"\uf06e","fa-eye-slash":"\uf070","fa-eyedropper":"\uf1fb","fa-facebook":"\uf09a","fa-facebook-f":"\uf09a","fa-facebook-official":"\uf230","fa-facebook-square":"\uf082","fa-fast-backward":"\uf049","fa-fast-forward":"\uf050","fa-fax":"\uf1ac","fa-feed":"\uf09e","fa-female":"\uf182","fa-fighter-jet":"\uf0fb","fa-file":"\uf15b","fa-file-archive-o":"\uf1c6","fa-file-audio-o":"\uf1c7","fa-file-code-o":"\uf1c9","fa-file-excel-o":"\uf1c3","fa-file-image-o":"\uf1c5","fa-file-movie-o":"\uf1c8","fa-file-o":"\uf016","fa-file-pdf-o":"\uf1c1","fa-file-photo-o":"\uf1c5","fa-file-picture-o":"\uf1c5","fa-file-powerpoint-o":"\uf1c4","fa-file-sound-o":"\uf1c7","fa-file-text":"\uf15c","fa-file-text-o":"\uf0f6","fa-file-video-o":"\uf1c8","fa-file-word-o":"\uf1c2","fa-file-zip-o":"\uf1c6","fa-files-o":"\uf0c5","fa-film":"\uf008","fa-filter":"\uf0b0","fa-fire":"\uf06d","fa-fire-extinguisher":"\uf134","fa-firefox":"\uf269","fa-flag":"\uf024","fa-flag-checkered":"\uf11e","fa-flag-o":"\uf11d","fa-flash":"\uf0e7","fa-flask":"\uf0c3","fa-flickr":"\uf16e","fa-floppy-o":"\uf0c7","fa-folder":"\uf07b","fa-folder-o":"\uf114","fa-folder-open":"\uf07c","fa-folder-open-o":"\uf115","fa-font":"\uf031","fa-fonticons":"\uf280","fa-forumbee":"\uf211","fa-forward":"\uf04e","fa-foursquare":"\uf180","fa-frown-o":"\uf119","fa-futbol-o":"\uf1e3","fa-gamepad":"\uf11b","fa-gavel":"\uf0e3","fa-gbp":"\uf154","fa-ge":"\uf1d1","fa-gear":"\uf013","fa-gears":"\uf085","fa-genderless":"\uf22d","fa-get-pocket":"\uf265","fa-gg":"\uf260","fa-gg-circle":"\uf261","fa-gift":"\uf06b","fa-git":"\uf1d3","fa-git-square":"\uf1d2","fa-github":"\uf09b","fa-github-alt":"\uf113","fa-github-square":"\uf092","fa-gittip":"\uf184","fa-glass":"\uf000","fa-globe":"\uf0ac","fa-google":"\uf1a0","fa-google-plus":"\uf0d5","fa-google-plus-square":"\uf0d4","fa-google-wallet":"\uf1ee","fa-graduation-cap":"\uf19d","fa-gratipay":"\uf184","fa-group":"\uf0c0","fa-h-square":"\uf0fd","fa-hacker-news":"\uf1d4","fa-hand-grab-o":"\uf255","fa-hand-lizard-o":"\uf258","fa-hand-o-down":"\uf0a7","fa-hand-o-left":"\uf0a5","fa-hand-o-right":"\uf0a4","fa-hand-o-up":"\uf0a6","fa-hand-paper-o":"\uf256","fa-hand-peace-o":"\uf25b","fa-hand-pointer-o":"\uf25a","fa-hand-rock-o":"\uf255","fa-hand-scissors-o":"\uf257","fa-hand-spock-o":"\uf259","fa-hand-stop-o":"\uf256","fa-hdd-o":"\uf0a0","fa-header":"\uf1dc","fa-headphones":"\uf025","fa-heart":"\uf004","fa-heart-o":"\uf08a","fa-heartbeat":"\uf21e","fa-history":"\uf1da","fa-home":"\uf015","fa-hospital-o":"\uf0f8","fa-hotel":"\uf236","fa-hourglass":"\uf254","fa-hourglass-1":"\uf251","fa-hourglass-2":"\uf252","fa-hourglass-3":"\uf253","fa-hourglass-end":"\uf253","fa-hourglass-half":"\uf252","fa-hourglass-o":"\uf250","fa-hourglass-start":"\uf251","fa-houzz":"\uf27c","fa-html5":"\uf13b","fa-i-cursor":"\uf246","fa-ils":"\uf20b","fa-image":"\uf03e","fa-inbox":"\uf01c","fa-indent":"\uf03c","fa-industry":"\uf275","fa-info":"\uf129","fa-info-circle":"\uf05a","fa-inr":"\uf156","fa-instagram":"\uf16d","fa-institution":"\uf19c","fa-internet-explorer":"\uf26b","fa-intersex":"\uf224","fa-ioxhost":"\uf208","fa-italic":"\uf033","fa-joomla":"\uf1aa","fa-jpy":"\uf157","fa-jsfiddle":"\uf1cc","fa-key":"\uf084","fa-keyboard-o":"\uf11c","fa-krw":"\uf159","fa-language":"\uf1ab","fa-laptop":"\uf109","fa-lastfm":"\uf202","fa-lastfm-square":"\uf203","fa-leaf":"\uf06c","fa-leanpub":"\uf212","fa-legal":"\uf0e3","fa-lemon-o":"\uf094","fa-level-down":"\uf149","fa-level-up":"\uf148","fa-life-bouy":"\uf1cd","fa-life-buoy":"\uf1cd","fa-life-ring":"\uf1cd","fa-life-saver":"\uf1cd","fa-lightbulb-o":"\uf0eb","fa-line-chart":"\uf201","fa-link":"\uf0c1","fa-linkedin":"\uf0e1","fa-linkedin-square":"\uf08c","fa-linux":"\uf17c","fa-list":"\uf03a","fa-list-alt":"\uf022","fa-list-ol":"\uf0cb","fa-list-ul":"\uf0ca","fa-location-arrow":"\uf124","fa-lock":"\uf023","fa-long-arrow-down":"\uf175","fa-long-arrow-alt-down":"\uf309","fa-long-arrow-left":"\uf177","fa-long-arrow-alt-left":"\uf30a","fa-long-arrow-right":"\uf178","fa-long-arrow-alt-right":"\uf30b","fa-long-arrow-up":"\uf176","fa-long-arrow-alt-up":"\uf30c","fa-magic":"\uf0d0","fa-magnet":"\uf076","fa-mail-forward":"\uf064","fa-mail-reply":"\uf112","fa-mail-reply-all":"\uf122","fa-male":"\uf183","fa-map":"\uf279","fa-map-marker":"\uf041","fa-map-o":"\uf278","fa-map-pin":"\uf276","fa-map-signs":"\uf277","fa-mars":"\uf222","fa-mars-double":"\uf227","fa-mars-stroke":"\uf229","fa-mars-stroke-h":"\uf22b","fa-mars-stroke-v":"\uf22a","fa-maxcdn":"\uf136","fa-meanpath":"\uf20c","fa-medium":"\uf23a","fa-medkit":"\uf0fa","fa-meh-o":"\uf11a","fa-mercury":"\uf223","fa-microphone":"\uf130","fa-microphone-slash":"\uf131","fa-minus":"\uf068","fa-minus-circle":"\uf056","fa-minus-square":"\uf146","fa-minus-square-o":"\uf147","fa-mobile":"\uf10b","fa-mobile-phone":"\uf10b","fa-money":"\uf0d6","fa-moon-o":"\uf186","fa-mortar-board":"\uf19d","fa-motorcycle":"\uf21c","fa-mouse-pointer":"\uf245","fa-music":"\uf001","fa-navicon":"\uf0c9","fa-neuter":"\uf22c","fa-newspaper-o":"\uf1ea","fa-object-group":"\uf247","fa-object-ungroup":"\uf248","fa-odnoklassniki":"\uf263","fa-odnoklassniki-square":"\uf264","fa-opencart":"\uf23d","fa-openid":"\uf19b","fa-opera":"\uf26a","fa-optin-monster":"\uf23c","fa-outdent":"\uf03b","fa-pagelines":"\uf18c","fa-paint-brush":"\uf1fc","fa-paper-plane":"\uf1d8","fa-paper-plane-o":"\uf1d9","fa-paperclip":"\uf0c6","fa-paragraph":"\uf1dd","fa-paste":"\uf0ea","fa-pause":"\uf04c","fa-paw":"\uf1b0","fa-paypal":"\uf1ed","fa-pencil":"\uf040","fa-pencil-square":"\uf14b","fa-pencil-square-o":"\uf044","fa-phone":"\uf095","fa-phone-square":"\uf098","fa-photo":"\uf03e","fa-picture-o":"\uf03e","fa-pie-chart":"\uf200","fa-pied-piper":"\uf1a7","fa-pied-piper-alt":"\uf1a8","fa-pinterest":"\uf0d2","fa-pinterest-p":"\uf231","fa-pinterest-square":"\uf0d3","fa-plane":"\uf072","fa-play":"\uf04b","fa-play-circle":"\uf144","fa-play-circle-o":"\uf01d","fa-plug":"\uf1e6","fa-plus":"\uf067","fa-plus-circle":"\uf055","fa-plus-square":"\uf0fe","fa-plus-square-o":"\uf196","fa-power-off":"\uf011","fa-print":"\uf02f","fa-puzzle-piece":"\uf12e","fa-qq":"\uf1d6","fa-qrcode":"\uf029","fa-question":"\uf128","fa-question-circle":"\uf059","fa-quote-left":"\uf10d","fa-quote-right":"\uf10e","fa-ra":"\uf1d0","fa-random":"\uf074","fa-rebel":"\uf1d0","fa-recycle":"\uf1b8","fa-reddit":"\uf1a1","fa-reddit-square":"\uf1a2","fa-refresh":"\uf021","fa-registered":"\uf25d","fa-remove":"\uf00d","fa-renren":"\uf18b","fa-reorder":"\uf0c9","fa-repeat":"\uf01e","fa-reply":"\uf112","fa-reply-all":"\uf122","fa-retweet":"\uf079","fa-rmb":"\uf157","fa-road":"\uf018","fa-rocket":"\uf135","fa-rotate-left":"\uf0e2","fa-rotate-right":"\uf01e","fa-rouble":"\uf158","fa-rss":"\uf09e","fa-rss-square":"\uf143","fa-rub":"\uf158","fa-ruble":"\uf158","fa-rupee":"\uf156","fa-safari":"\uf267","fa-save":"\uf0c7","fa-scissors":"\uf0c4","fa-search":"\uf002","fa-search-minus":"\uf010","fa-search-plus":"\uf00e","fa-sellsy":"\uf213","fa-send":"\uf1d8","fa-send-o":"\uf1d9","fa-server":"\uf233","fa-share":"\uf064","fa-share-alt":"\uf1e0","fa-share-alt-square":"\uf1e1","fa-share-square":"\uf14d","fa-share-square-o":"\uf045","fa-shekel":"\uf20b","fa-sheqel":"\uf20b","fa-shield":"\uf132","fa-ship":"\uf21a","fa-shirtsinbulk":"\uf214","fa-shopping-cart":"\uf07a","fa-sign-in":"\uf090","fa-sign-out":"\uf08b","fa-signal":"\uf012","fa-simplybuilt":"\uf215","fa-sitemap":"\uf0e8","fa-skyatlas":"\uf216","fa-skype":"\uf17e","fa-slack":"\uf198","fa-sliders":"\uf1de","fa-slideshare":"\uf1e7","fa-smile-o":"\uf118","fa-soccer-ball-o":"\uf1e3","fa-sort":"\uf0dc","fa-sort-alpha-asc":"\uf15d","fa-sort-alpha-desc":"\uf15e","fa-sort-amount-asc":"\uf160","fa-sort-amount-desc":"\uf161","fa-sort-asc":"\uf0de","fa-sort-desc":"\uf0dd","fa-sort-down":"\uf0dd","fa-sort-numeric-asc":"\uf162","fa-sort-numeric-desc":"\uf163","fa-sort-up":"\uf0de","fa-soundcloud":"\uf1be","fa-space-shuttle":"\uf197","fa-spinner":"\uf110","fa-spoon":"\uf1b1","fa-spotify":"\uf1bc","fa-square":"\uf0c8","fa-square-o":"\uf096","fa-stack-exchange":"\uf18d","fa-stack-overflow":"\uf16c","fa-star":"\uf005","fa-star-half":"\uf089","fa-star-half-empty":"\uf123","fa-star-half-full":"\uf123","fa-star-half-o":"\uf123","fa-star-o":"\uf006","fa-steam":"\uf1b6","fa-steam-square":"\uf1b7","fa-step-backward":"\uf048","fa-step-forward":"\uf051","fa-stethoscope":"\uf0f1","fa-sticky-note":"\uf249","fa-sticky-note-o":"\uf24a","fa-stop":"\uf04d","fa-street-view":"\uf21d","fa-strikethrough":"\uf0cc","fa-stumbleupon":"\uf1a4","fa-stumbleupon-circle":"\uf1a3","fa-subscript":"\uf12c","fa-subway":"\uf239","fa-suitcase":"\uf0f2","fa-sun-o":"\uf185","fa-superscript":"\uf12b","fa-support":"\uf1cd","fa-table":"\uf0ce","fa-tablet":"\uf10a","fa-tachometer":"\uf0e4","fa-tag":"\uf02b","fa-tags":"\uf02c","fa-tasks":"\uf0ae","fa-taxi":"\uf1ba","fa-television":"\uf26c","fa-tencent-weibo":"\uf1d5","fa-terminal":"\uf120","fa-text-height":"\uf034","fa-text-width":"\uf035","fa-th":"\uf00a","fa-th-large":"\uf009","fa-th-list":"\uf00b","fa-thumb-tack":"\uf08d","fa-thumbs-down":"\uf165","fa-thumbs-o-down":"\uf088","fa-thumbs-o-up":"\uf087","fa-thumbs-up":"\uf164","fa-ticket":"\uf145","fa-times":"\uf00d","fa-times-circle":"\uf057","fa-times-circle-o":"\uf05c","fa-tint":"\uf043","fa-toggle-down":"\uf150","fa-toggle-left":"\uf191","fa-toggle-off":"\uf204","fa-toggle-on":"\uf205","fa-toggle-right":"\uf152","fa-toggle-up":"\uf151","fa-trademark":"\uf25c","fa-train":"\uf238","fa-transgender":"\uf224","fa-transgender-alt":"\uf225","fa-trash":"\uf1f8","fa-trash-o":"\uf014","fa-tree":"\uf1bb","fa-trello":"\uf181","fa-tripadvisor":"\uf262","fa-trophy":"\uf091","fa-truck":"\uf0d1","fa-try":"\uf195","fa-tty":"\uf1e4","fa-tumblr":"\uf173","fa-tumblr-square":"\uf174","fa-turkish-lira":"\uf195","fa-tv":"\uf26c","fa-twitch":"\uf1e8","fa-twitter":"\uf099","fa-twitter-square":"\uf081","fa-umbrella":"\uf0e9","fa-underline":"\uf0cd","fa-undo":"\uf0e2","fa-university":"\uf19c","fa-unlink":"\uf127","fa-unlock":"\uf09c","fa-unlock-alt":"\uf13e","fa-unsorted":"\uf0dc","fa-upload":"\uf093","fa-usd":"\uf155","fa-user":"\uf007","fa-user-md":"\uf0f0","fa-user-plus":"\uf234","fa-user-secret":"\uf21b","fa-user-times":"\uf235","fa-users":"\uf0c0","fa-venus":"\uf221","fa-venus-double":"\uf226","fa-venus-mars":"\uf228","fa-viacoin":"\uf237","fa-video-camera":"\uf03d","fa-vimeo":"\uf27d","fa-vimeo-square":"\uf194","fa-vine":"\uf1ca","fa-vk":"\uf189","fa-volume-down":"\uf027","fa-volume-off":"\uf026","fa-volume-up":"\uf028","fa-warning":"\uf071","fa-wechat":"\uf1d7","fa-weibo":"\uf18a","fa-weixin":"\uf1d7","fa-whatsapp":"\uf232","fa-wheelchair":"\uf193","fa-wifi":"\uf1eb","fa-wikipedia-w":"\uf266","fa-windows":"\uf17a","fa-won":"\uf159","fa-wordpress":"\uf19a","fa-wrench":"\uf0ad","fa-xing":"\uf168","fa-xing-square":"\uf169","fa-y-combinator":"\uf23b","fa-y-combinator-square":"\uf1d4","fa-yahoo":"\uf19e","fa-yc":"\uf23b","fa-yc-square":"\uf1d4","fa-yelp":"\uf1e9","fa-yen":"\uf157","fa-youtube":"\uf167","fa-youtube-play":"\uf16a","fa-youtube-square":"\uf166"}; + var FONT_AWESOME = {"fa-500px":"\uf26e","fa-adjust":"\uf042","fa-adn":"\uf170","fa-align-center":"\uf037","fa-align-justify":"\uf039","fa-align-left":"\uf036","fa-align-right":"\uf038","fa-amazon":"\uf270","fa-ambulance":"\uf0f9","fa-anchor":"\uf13d","fa-android":"\uf17b","fa-angellist":"\uf209","fa-angle-double-down":"\uf103","fa-angle-double-left":"\uf100","fa-angle-double-right":"\uf101","fa-angle-double-up":"\uf102","fa-angle-down":"\uf107","fa-angle-left":"\uf104","fa-angle-right":"\uf105","fa-angle-up":"\uf106","fa-apple":"\uf179","fa-archive":"\uf187","fa-area-chart":"\uf1fe","fa-arrow-circle-down":"\uf0ab","fa-arrow-circle-left":"\uf0a8","fa-arrow-circle-o-down":"\uf01a","fa-arrow-circle-o-left":"\uf190","fa-arrow-circle-o-right":"\uf18e","fa-arrow-circle-o-up":"\uf01b","fa-arrow-circle-right":"\uf0a9","fa-arrow-circle-up":"\uf0aa","fa-arrow-down":"\uf063","fa-arrow-left":"\uf060","fa-arrow-right":"\uf061","fa-arrow-up":"\uf062","fa-arrows":"\uf047","fa-arrows-alt":"\uf0b2","fa-arrows-h":"\uf07e","fa-arrows-v":"\uf07d","fa-asterisk":"\uf069","fa-at":"\uf1fa","fa-automobile":"\uf1b9","fa-backward":"\uf04a","fa-balance-scale":"\uf24e","fa-ban":"\uf05e","fa-bank":"\uf19c","fa-bar-chart":"\uf080","fa-bar-chart-o":"\uf080","fa-barcode":"\uf02a","fa-bars":"\uf0c9","fa-battery-0":"\uf244","fa-battery-1":"\uf243","fa-battery-2":"\uf242","fa-battery-3":"\uf241","fa-battery-4":"\uf240","fa-battery-empty":"\uf244","fa-battery-full":"\uf240","fa-battery-half":"\uf242","fa-battery-quarter":"\uf243","fa-battery-three-quarters":"\uf241","fa-bed":"\uf236","fa-beer":"\uf0fc","fa-behance":"\uf1b4","fa-behance-square":"\uf1b5","fa-bell":"\uf0f3","fa-bell-o":"\uf0a2","fa-bell-slash":"\uf1f6","fa-bell-slash-o":"\uf1f7","fa-bicycle":"\uf206","fa-binoculars":"\uf1e5","fa-birthday-cake":"\uf1fd","fa-bitbucket":"\uf171","fa-bitbucket-square":"\uf172","fa-bitcoin":"\uf15a","fa-black-tie":"\uf27e","fa-bold":"\uf032","fa-bolt":"\uf0e7","fa-bomb":"\uf1e2","fa-book":"\uf02d","fa-bookmark":"\uf02e","fa-bookmark-o":"\uf097","fa-briefcase":"\uf0b1","fa-btc":"\uf15a","fa-bug":"\uf188","fa-building":"\uf1ad","fa-building-o":"\uf0f7","fa-bullhorn":"\uf0a1","fa-bullseye":"\uf140","fa-bus":"\uf207","fa-buysellads":"\uf20d","fa-cab":"\uf1ba","fa-calculator":"\uf1ec","fa-calendar":"\uf073","fa-calendar-check-o":"\uf274","fa-calendar-minus-o":"\uf272","fa-calendar-o":"\uf133","fa-calendar-plus-o":"\uf271","fa-calendar-times-o":"\uf273","fa-camera":"\uf030","fa-camera-retro":"\uf083","fa-car":"\uf1b9","fa-caret-down":"\uf0d7","fa-caret-left":"\uf0d9","fa-caret-right":"\uf0da","fa-caret-square-o-down":"\uf150","fa-caret-square-o-left":"\uf191","fa-caret-square-o-right":"\uf152","fa-caret-square-o-up":"\uf151","fa-caret-up":"\uf0d8","fa-cart-arrow-down":"\uf218","fa-cart-plus":"\uf217","fa-cc":"\uf20a","fa-cc-amex":"\uf1f3","fa-cc-diners-club":"\uf24c","fa-cc-discover":"\uf1f2","fa-cc-jcb":"\uf24b","fa-cc-mastercard":"\uf1f1","fa-cc-paypal":"\uf1f4","fa-cc-stripe":"\uf1f5","fa-cc-visa":"\uf1f0","fa-certificate":"\uf0a3","fa-chain":"\uf0c1","fa-chain-broken":"\uf127","fa-check":"\uf00c","fa-check-circle":"\uf058","fa-check-circle-o":"\uf05d","fa-check-square":"\uf14a","fa-check-square-o":"\uf046","fa-chevron-circle-down":"\uf13a","fa-chevron-circle-left":"\uf137","fa-chevron-circle-right":"\uf138","fa-chevron-circle-up":"\uf139","fa-chevron-down":"\uf078","fa-chevron-left":"\uf053","fa-chevron-right":"\uf054","fa-chevron-up":"\uf077","fa-child":"\uf1ae","fa-chrome":"\uf268","fa-circle":"\uf111","fa-circle-o":"\uf10c","fa-circle-o-notch":"\uf1ce","fa-circle-thin":"\uf1db","fa-clipboard":"\uf0ea","fa-clock-o":"\uf017","fa-clone":"\uf24d","fa-close":"\uf00d","fa-cloud":"\uf0c2","fa-cloud-download":"\uf0ed","fa-cloud-upload":"\uf0ee","fa-cny":"\uf157","fa-code":"\uf121","fa-code-fork":"\uf126","fa-codepen":"\uf1cb","fa-coffee":"\uf0f4","fa-cog":"\uf013","fa-cogs":"\uf085","fa-columns":"\uf0db","fa-comment":"\uf075","fa-comment-o":"\uf0e5","fa-commenting":"\uf27a","fa-commenting-o":"\uf27b","fa-comments":"\uf086","fa-comments-o":"\uf0e6","fa-compass":"\uf14e","fa-compress":"\uf066","fa-connectdevelop":"\uf20e","fa-contao":"\uf26d","fa-copy":"\uf0c5","fa-copyright":"\uf1f9","fa-creative-commons":"\uf25e","fa-credit-card":"\uf09d","fa-crop":"\uf125","fa-crosshairs":"\uf05b","fa-css3":"\uf13c","fa-cube":"\uf1b2","fa-cubes":"\uf1b3","fa-cut":"\uf0c4","fa-cutlery":"\uf0f5","fa-dashboard":"\uf0e4","fa-dashcube":"\uf210","fa-database":"\uf1c0","fa-dedent":"\uf03b","fa-delicious":"\uf1a5","fa-desktop":"\uf108","fa-deviantart":"\uf1bd","fa-diamond":"\uf219","fa-digg":"\uf1a6","fa-dollar":"\uf155","fa-dot-circle-o":"\uf192","fa-download":"\uf019","fa-dribbble":"\uf17d","fa-dropbox":"\uf16b","fa-drupal":"\uf1a9","fa-edit":"\uf044","fa-eject":"\uf052","fa-ellipsis-h":"\uf141","fa-ellipsis-v":"\uf142","fa-empire":"\uf1d1","fa-envelope":"\uf0e0","fa-envelope-o":"\uf003","fa-envelope-square":"\uf199","fa-eraser":"\uf12d","fa-eur":"\uf153","fa-euro":"\uf153","fa-exchange":"\uf0ec","fa-exclamation":"\uf12a","fa-exclamation-circle":"\uf06a","fa-exclamation-triangle":"\uf071","fa-expand":"\uf065","fa-expeditedssl":"\uf23e","fa-external-link":"\uf08e","fa-external-link-square":"\uf14c","fa-eye":"\uf06e","fa-eye-slash":"\uf070","fa-eyedropper":"\uf1fb","fa-facebook":"\uf09a","fa-facebook-f":"\uf09a","fa-facebook-official":"\uf230","fa-facebook-square":"\uf082","fa-fast-backward":"\uf049","fa-fast-forward":"\uf050","fa-fax":"\uf1ac","fa-feed":"\uf09e","fa-female":"\uf182","fa-fighter-jet":"\uf0fb","fa-file":"\uf15b","fa-file-archive-o":"\uf1c6","fa-file-audio-o":"\uf1c7","fa-file-code-o":"\uf1c9","fa-file-excel-o":"\uf1c3","fa-file-image-o":"\uf1c5","fa-file-movie-o":"\uf1c8","fa-file-o":"\uf016","fa-file-pdf-o":"\uf1c1","fa-file-photo-o":"\uf1c5","fa-file-picture-o":"\uf1c5","fa-file-powerpoint-o":"\uf1c4","fa-file-sound-o":"\uf1c7","fa-file-text":"\uf15c","fa-file-text-o":"\uf0f6","fa-file-video-o":"\uf1c8","fa-file-word-o":"\uf1c2","fa-file-zip-o":"\uf1c6","fa-files-o":"\uf0c5","fa-film":"\uf008","fa-filter":"\uf0b0","fa-fire":"\uf06d","fa-fire-extinguisher":"\uf134","fa-firefox":"\uf269","fa-flag":"\uf024","fa-flag-checkered":"\uf11e","fa-flag-o":"\uf11d","fa-flash":"\uf0e7","fa-flask":"\uf0c3","fa-flickr":"\uf16e","fa-floppy-o":"\uf0c7","fa-folder":"\uf07b","fa-folder-o":"\uf114","fa-folder-open":"\uf07c","fa-folder-open-o":"\uf115","fa-font":"\uf031","fa-fonticons":"\uf280","fa-forumbee":"\uf211","fa-forward":"\uf04e","fa-foursquare":"\uf180","fa-frown-o":"\uf119","fa-futbol-o":"\uf1e3","fa-gamepad":"\uf11b","fa-gavel":"\uf0e3","fa-gbp":"\uf154","fa-ge":"\uf1d1","fa-gear":"\uf013","fa-gears":"\uf085","fa-genderless":"\uf22d","fa-get-pocket":"\uf265","fa-gg":"\uf260","fa-gg-circle":"\uf261","fa-gift":"\uf06b","fa-git":"\uf1d3","fa-git-square":"\uf1d2","fa-github":"\uf09b","fa-github-alt":"\uf113","fa-github-square":"\uf092","fa-gittip":"\uf184","fa-glass":"\uf000","fa-globe":"\uf0ac","fa-google":"\uf1a0","fa-google-plus":"\uf0d5","fa-google-plus-square":"\uf0d4","fa-google-wallet":"\uf1ee","fa-graduation-cap":"\uf19d","fa-gratipay":"\uf184","fa-group":"\uf0c0","fa-h-square":"\uf0fd","fa-hacker-news":"\uf1d4","fa-hand-grab-o":"\uf255","fa-hand-lizard-o":"\uf258","fa-hand-o-down":"\uf0a7","fa-hand-o-left":"\uf0a5","fa-hand-o-right":"\uf0a4","fa-hand-o-up":"\uf0a6","fa-hand-paper-o":"\uf256","fa-hand-peace-o":"\uf25b","fa-hand-pointer-o":"\uf25a","fa-hand-rock-o":"\uf255","fa-hand-scissors-o":"\uf257","fa-hand-spock-o":"\uf259","fa-hand-stop-o":"\uf256","fa-hdd-o":"\uf0a0","fa-header":"\uf1dc","fa-headphones":"\uf025","fa-heart":"\uf004","fa-heart-o":"\uf08a","fa-heartbeat":"\uf21e","fa-history":"\uf1da","fa-home":"\uf015","fa-hospital-o":"\uf0f8","fa-hotel":"\uf236","fa-hourglass":"\uf254","fa-hourglass-1":"\uf251","fa-hourglass-2":"\uf252","fa-hourglass-3":"\uf253","fa-hourglass-end":"\uf253","fa-hourglass-half":"\uf252","fa-hourglass-o":"\uf250","fa-hourglass-start":"\uf251","fa-houzz":"\uf27c","fa-html5":"\uf13b","fa-i-cursor":"\uf246","fa-ils":"\uf20b","fa-image":"\uf03e","fa-inbox":"\uf01c","fa-indent":"\uf03c","fa-industry":"\uf275","fa-info":"\uf129","fa-info-circle":"\uf05a","fa-inr":"\uf156","fa-instagram":"\uf16d","fa-institution":"\uf19c","fa-internet-explorer":"\uf26b","fa-intersex":"\uf224","fa-ioxhost":"\uf208","fa-italic":"\uf033","fa-joomla":"\uf1aa","fa-jpy":"\uf157","fa-jsfiddle":"\uf1cc","fa-key":"\uf084","fa-keyboard-o":"\uf11c","fa-krw":"\uf159","fa-language":"\uf1ab","fa-laptop":"\uf109","fa-lastfm":"\uf202","fa-lastfm-square":"\uf203","fa-leaf":"\uf06c","fa-leanpub":"\uf212","fa-legal":"\uf0e3","fa-lemon-o":"\uf094","fa-level-down":"\uf149","fa-level-up":"\uf148","fa-life-bouy":"\uf1cd","fa-life-buoy":"\uf1cd","fa-life-ring":"\uf1cd","fa-life-saver":"\uf1cd","fa-lightbulb-o":"\uf0eb","fa-line-chart":"\uf201","fa-link":"\uf0c1","fa-linkedin":"\uf0e1","fa-linkedin-square":"\uf08c","fa-linux":"\uf17c","fa-list":"\uf03a","fa-list-alt":"\uf022","fa-list-ol":"\uf0cb","fa-list-ul":"\uf0ca","fa-location-arrow":"\uf124","fa-lock":"\uf023","fa-long-arrow-down":"\uf175","fa-long-arrow-left":"\uf177","fa-long-arrow-right":"\uf178","fa-long-arrow-up":"\uf176","fa-magic":"\uf0d0","fa-magnet":"\uf076","fa-mail-forward":"\uf064","fa-mail-reply":"\uf112","fa-mail-reply-all":"\uf122","fa-male":"\uf183","fa-map":"\uf279","fa-map-marker":"\uf041","fa-map-o":"\uf278","fa-map-pin":"\uf276","fa-map-signs":"\uf277","fa-mars":"\uf222","fa-mars-double":"\uf227","fa-mars-stroke":"\uf229","fa-mars-stroke-h":"\uf22b","fa-mars-stroke-v":"\uf22a","fa-maxcdn":"\uf136","fa-meanpath":"\uf20c","fa-medium":"\uf23a","fa-medkit":"\uf0fa","fa-meh-o":"\uf11a","fa-mercury":"\uf223","fa-microphone":"\uf130","fa-microphone-slash":"\uf131","fa-minus":"\uf068","fa-minus-circle":"\uf056","fa-minus-square":"\uf146","fa-minus-square-o":"\uf147","fa-mobile":"\uf10b","fa-mobile-phone":"\uf10b","fa-money":"\uf0d6","fa-moon-o":"\uf186","fa-mortar-board":"\uf19d","fa-motorcycle":"\uf21c","fa-mouse-pointer":"\uf245","fa-music":"\uf001","fa-navicon":"\uf0c9","fa-neuter":"\uf22c","fa-newspaper-o":"\uf1ea","fa-object-group":"\uf247","fa-object-ungroup":"\uf248","fa-odnoklassniki":"\uf263","fa-odnoklassniki-square":"\uf264","fa-opencart":"\uf23d","fa-openid":"\uf19b","fa-opera":"\uf26a","fa-optin-monster":"\uf23c","fa-outdent":"\uf03b","fa-pagelines":"\uf18c","fa-paint-brush":"\uf1fc","fa-paper-plane":"\uf1d8","fa-paper-plane-o":"\uf1d9","fa-paperclip":"\uf0c6","fa-paragraph":"\uf1dd","fa-paste":"\uf0ea","fa-pause":"\uf04c","fa-paw":"\uf1b0","fa-paypal":"\uf1ed","fa-pencil":"\uf040","fa-pencil-square":"\uf14b","fa-pencil-square-o":"\uf044","fa-phone":"\uf095","fa-phone-square":"\uf098","fa-photo":"\uf03e","fa-picture-o":"\uf03e","fa-pie-chart":"\uf200","fa-pied-piper":"\uf1a7","fa-pied-piper-alt":"\uf1a8","fa-pinterest":"\uf0d2","fa-pinterest-p":"\uf231","fa-pinterest-square":"\uf0d3","fa-plane":"\uf072","fa-play":"\uf04b","fa-play-circle":"\uf144","fa-play-circle-o":"\uf01d","fa-plug":"\uf1e6","fa-plus":"\uf067","fa-plus-circle":"\uf055","fa-plus-square":"\uf0fe","fa-plus-square-o":"\uf196","fa-power-off":"\uf011","fa-print":"\uf02f","fa-puzzle-piece":"\uf12e","fa-qq":"\uf1d6","fa-qrcode":"\uf029","fa-question":"\uf128","fa-question-circle":"\uf059","fa-quote-left":"\uf10d","fa-quote-right":"\uf10e","fa-ra":"\uf1d0","fa-random":"\uf074","fa-rebel":"\uf1d0","fa-recycle":"\uf1b8","fa-reddit":"\uf1a1","fa-reddit-square":"\uf1a2","fa-refresh":"\uf021","fa-registered":"\uf25d","fa-remove":"\uf00d","fa-renren":"\uf18b","fa-reorder":"\uf0c9","fa-repeat":"\uf01e","fa-reply":"\uf112","fa-reply-all":"\uf122","fa-retweet":"\uf079","fa-rmb":"\uf157","fa-road":"\uf018","fa-rocket":"\uf135","fa-rotate-left":"\uf0e2","fa-rotate-right":"\uf01e","fa-rouble":"\uf158","fa-rss":"\uf09e","fa-rss-square":"\uf143","fa-rub":"\uf158","fa-ruble":"\uf158","fa-rupee":"\uf156","fa-safari":"\uf267","fa-save":"\uf0c7","fa-scissors":"\uf0c4","fa-search":"\uf002","fa-search-minus":"\uf010","fa-search-plus":"\uf00e","fa-sellsy":"\uf213","fa-send":"\uf1d8","fa-send-o":"\uf1d9","fa-server":"\uf233","fa-share":"\uf064","fa-share-alt":"\uf1e0","fa-share-alt-square":"\uf1e1","fa-share-square":"\uf14d","fa-share-square-o":"\uf045","fa-shekel":"\uf20b","fa-sheqel":"\uf20b","fa-shield":"\uf132","fa-ship":"\uf21a","fa-shirtsinbulk":"\uf214","fa-shopping-cart":"\uf07a","fa-sign-in":"\uf090","fa-sign-out":"\uf08b","fa-signal":"\uf012","fa-simplybuilt":"\uf215","fa-sitemap":"\uf0e8","fa-skyatlas":"\uf216","fa-skype":"\uf17e","fa-slack":"\uf198","fa-sliders":"\uf1de","fa-slideshare":"\uf1e7","fa-smile-o":"\uf118","fa-soccer-ball-o":"\uf1e3","fa-sort":"\uf0dc","fa-sort-alpha-asc":"\uf15d","fa-sort-alpha-desc":"\uf15e","fa-sort-amount-asc":"\uf160","fa-sort-amount-desc":"\uf161","fa-sort-asc":"\uf0de","fa-sort-desc":"\uf0dd","fa-sort-down":"\uf0dd","fa-sort-numeric-asc":"\uf162","fa-sort-numeric-desc":"\uf163","fa-sort-up":"\uf0de","fa-soundcloud":"\uf1be","fa-space-shuttle":"\uf197","fa-spinner":"\uf110","fa-spoon":"\uf1b1","fa-spotify":"\uf1bc","fa-square":"\uf0c8","fa-square-o":"\uf096","fa-stack-exchange":"\uf18d","fa-stack-overflow":"\uf16c","fa-star":"\uf005","fa-star-half":"\uf089","fa-star-half-empty":"\uf123","fa-star-half-full":"\uf123","fa-star-half-o":"\uf123","fa-star-o":"\uf006","fa-steam":"\uf1b6","fa-steam-square":"\uf1b7","fa-step-backward":"\uf048","fa-step-forward":"\uf051","fa-stethoscope":"\uf0f1","fa-sticky-note":"\uf249","fa-sticky-note-o":"\uf24a","fa-stop":"\uf04d","fa-street-view":"\uf21d","fa-strikethrough":"\uf0cc","fa-stumbleupon":"\uf1a4","fa-stumbleupon-circle":"\uf1a3","fa-subscript":"\uf12c","fa-subway":"\uf239","fa-suitcase":"\uf0f2","fa-sun-o":"\uf185","fa-superscript":"\uf12b","fa-support":"\uf1cd","fa-table":"\uf0ce","fa-tablet":"\uf10a","fa-tachometer":"\uf0e4","fa-tag":"\uf02b","fa-tags":"\uf02c","fa-tasks":"\uf0ae","fa-taxi":"\uf1ba","fa-television":"\uf26c","fa-tencent-weibo":"\uf1d5","fa-terminal":"\uf120","fa-text-height":"\uf034","fa-text-width":"\uf035","fa-th":"\uf00a","fa-th-large":"\uf009","fa-th-list":"\uf00b","fa-thumb-tack":"\uf08d","fa-thumbs-down":"\uf165","fa-thumbs-o-down":"\uf088","fa-thumbs-o-up":"\uf087","fa-thumbs-up":"\uf164","fa-ticket":"\uf145","fa-times":"\uf00d","fa-times-circle":"\uf057","fa-times-circle-o":"\uf05c","fa-tint":"\uf043","fa-toggle-down":"\uf150","fa-toggle-left":"\uf191","fa-toggle-off":"\uf204","fa-toggle-on":"\uf205","fa-toggle-right":"\uf152","fa-toggle-up":"\uf151","fa-trademark":"\uf25c","fa-train":"\uf238","fa-transgender":"\uf224","fa-transgender-alt":"\uf225","fa-trash":"\uf1f8","fa-trash-o":"\uf014","fa-tree":"\uf1bb","fa-trello":"\uf181","fa-tripadvisor":"\uf262","fa-trophy":"\uf091","fa-truck":"\uf0d1","fa-try":"\uf195","fa-tty":"\uf1e4","fa-tumblr":"\uf173","fa-tumblr-square":"\uf174","fa-turkish-lira":"\uf195","fa-tv":"\uf26c","fa-twitch":"\uf1e8","fa-twitter":"\uf099","fa-twitter-square":"\uf081","fa-umbrella":"\uf0e9","fa-underline":"\uf0cd","fa-undo":"\uf0e2","fa-university":"\uf19c","fa-unlink":"\uf127","fa-unlock":"\uf09c","fa-unlock-alt":"\uf13e","fa-unsorted":"\uf0dc","fa-upload":"\uf093","fa-usd":"\uf155","fa-user":"\uf007","fa-user-md":"\uf0f0","fa-user-plus":"\uf234","fa-user-secret":"\uf21b","fa-user-times":"\uf235","fa-users":"\uf0c0","fa-venus":"\uf221","fa-venus-double":"\uf226","fa-venus-mars":"\uf228","fa-viacoin":"\uf237","fa-video-camera":"\uf03d","fa-vimeo":"\uf27d","fa-vimeo-square":"\uf194","fa-vine":"\uf1ca","fa-vk":"\uf189","fa-volume-down":"\uf027","fa-volume-off":"\uf026","fa-volume-up":"\uf028","fa-warning":"\uf071","fa-wechat":"\uf1d7","fa-weibo":"\uf18a","fa-weixin":"\uf1d7","fa-whatsapp":"\uf232","fa-wheelchair":"\uf193","fa-wifi":"\uf1eb","fa-wikipedia-w":"\uf266","fa-windows":"\uf17a","fa-won":"\uf159","fa-wordpress":"\uf19a","fa-wrench":"\uf0ad","fa-xing":"\uf168","fa-xing-square":"\uf169","fa-y-combinator":"\uf23b","fa-y-combinator-square":"\uf1d4","fa-yahoo":"\uf19e","fa-yc":"\uf23b","fa-yc-square":"\uf1d4","fa-yelp":"\uf1e9","fa-yen":"\uf157","fa-youtube":"\uf167","fa-youtube-play":"\uf16a","fa-youtube-square":"\uf166"}; var FONT_OPENAUTOMATION = {"oa-weather_winter":"\ue600","oa-weather_wind_speed":"\ue601","oa-weather_wind_directions_w":"\ue602","oa-weather_wind_directions_sw":"\ue603","oa-weather_wind_directions_se":"\ue604","oa-weather_wind_directions_s":"\ue605","oa-weather_wind_directions_nw":"\ue606","oa-weather_wind_directions_ne":"\ue607","oa-weather_wind_directions_n":"\ue608","oa-weather_wind_directions_e":"\ue609","oa-weather_wind":"\ue60a","oa-weather_thunderstorm":"\ue60b","oa-weather_sunset":"\ue60c","oa-weather_sunrise":"\ue60d","oa-weather_sun":"\ue60e","oa-weather_summer":"\ue60f","oa-weather_storm":"\ue610","oa-weather_station_quadra":"\ue611","oa-weather_station":"\ue612","oa-weather_snow_light":"\ue613","oa-weather_snow_heavy":"\ue614","oa-weather_snow":"\ue615","oa-weather_rain_meter":"\ue616","oa-weather_rain_light":"\ue617","oa-weather_rain_heavy":"\ue618","oa-weather_rain_gauge":"\ue619","oa-weather_rain":"\ue61a","oa-weather_pollen":"\ue61b","oa-weather_moonset":"\ue61c","oa-weather_moonrise":"\ue61d","oa-weather_moon_phases_8":"\ue61e","oa-weather_moon_phases_7_half":"\ue61f","oa-weather_moon_phases_6":"\ue620","oa-weather_moon_phases_5_full":"\ue621","oa-weather_moon_phases_4":"\ue622","oa-weather_moon_phases_3_half":"\ue623","oa-weather_moon_phases_2":"\ue624","oa-weather_moon_phases_1_new":"\ue625","oa-weather_light_meter":"\ue626","oa-weather_humidity":"\ue627","oa-weather_frost":"\ue628","oa-weather_directions":"\ue629","oa-weather_cloudy_light":"\ue62a","oa-weather_cloudy_heavy":"\ue62b","oa-weather_cloudy":"\ue62c","oa-weather_barometric_pressure":"\ue62d","oa-weather_baraometric_pressure":"\ue62e","oa-vent_ventilation_level_manual_m":"\ue62f","oa-vent_ventilation_level_automatic":"\ue630","oa-vent_ventilation_level_3":"\ue631","oa-vent_ventilation_level_2":"\ue632","oa-vent_ventilation_level_1":"\ue633","oa-vent_ventilation_level_0":"\ue634","oa-vent_ventilation_control":"\ue635","oa-vent_ventilation":"\ue636","oa-vent_used_air":"\ue637","oa-vent_supply_air":"\ue638","oa-vent_exhaust_air":"\ue639","oa-vent_bypass":"\ue63a","oa-vent_ambient_air":"\ue63b","oa-user_ext_away":"\ue63c","oa-user_away":"\ue63d","oa-user_available":"\ue63e","oa-time_timer":"\ue63f","oa-time_statistic":"\ue640","oa-time_note":"\ue641","oa-time_manual_mode":"\ue642","oa-time_graph":"\ue643","oa-time_eco_mode":"\ue644","oa-time_clock":"\ue645","oa-time_calendar":"\ue646","oa-time_automatic":"\ue647","oa-text_min":"\ue648","oa-text_max":"\ue649","oa-temp_windchill":"\ue64a","oa-temp_temperature_min":"\ue64b","oa-temp_temperature_max":"\ue64c","oa-temp_temperature":"\ue64d","oa-temp_outside":"\ue64e","oa-temp_inside":"\ue64f","oa-temp_frost":"\ue650","oa-temp_control":"\ue651","oa-status_standby":"\ue652","oa-status_open":"\ue653","oa-status_night":"\ue654","oa-status_locked":"\ue655","oa-status_frost":"\ue656","oa-status_comfort":"\ue657","oa-status_away_2":"\ue658","oa-status_away_1":"\ue659","oa-status_available":"\ue65a","oa-status_automatic":"\ue65b","oa-secur_smoke_detector":"\ue65c","oa-secur_open":"\ue65d","oa-secur_locked":"\ue65e","oa-secur_heat_protection":"\ue65f","oa-secur_frost_protection":"\ue660","oa-secur_encoding":"\ue661","oa-secur_alarm":"\ue662","oa-scene_x-mas":"\ue663","oa-scene_workshop":"\ue664","oa-scene_wine_cellar":"\ue665","oa-scene_washing_machine":"\ue666","oa-scene_visit_guests":"\ue667","oa-scene_toilet_alternat":"\ue668","oa-scene_toilet":"\ue669","oa-scene_terrace":"\ue66a","oa-scene_swimming":"\ue66b","oa-scene_summerhouse":"\ue66c","oa-scene_stove":"\ue66d","oa-scene_storeroom":"\ue66e","oa-scene_stairs":"\ue66f","oa-scene_sleeping_alternat":"\ue670","oa-scene_sleeping":"\ue671","oa-scene_shower":"\ue672","oa-scene_scene":"\ue673","oa-scene_sauna":"\ue674","oa-scene_robo_lawnmower":"\ue675","oa-scene_pool":"\ue676","oa-scene_party":"\ue677","oa-scene_office":"\ue678","oa-scene_night":"\ue679","oa-scene_microwave_oven":"\ue67a","oa-scene_making_love_clean":"\ue67b","oa-scene_making_love":"\ue67c","oa-scene_livingroom":"\ue67d","oa-scene_laundry_room_fem":"\ue67e","oa-scene_laundry_room":"\ue67f","oa-scene_keyboard":"\ue680","oa-scene_hall":"\ue681","oa-scene_garden":"\ue682","oa-scene_gaming":"\ue683","oa-scene_fitness":"\ue684","oa-scene_dressing_room":"\ue685","oa-scene_dishwasher":"\ue686","oa-scene_dinner":"\ue687","oa-scene_day":"\ue688","oa-scene_cubby":"\ue689","oa-scene_cooking":"\ue68a","oa-scene_cockle_stove":"\ue68b","oa-scene_clothes_dryer":"\ue68c","oa-scene_cleaning":"\ue68d","oa-scene_cinema":"\ue68e","oa-scene_childs_room":"\ue68f","oa-scene_bathroom":"\ue690","oa-scene_bath":"\ue691","oa-scene_baking_oven":"\ue692","oa-scene_baby":"\ue693","oa-sani_water_tap":"\ue694","oa-sani_water_hot":"\ue695","oa-sani_water_cold":"\ue696","oa-sani_supply_temp":"\ue697","oa-sani_sprinkling":"\ue698","oa-sani_solar_temp":"\ue699","oa-sani_solar":"\ue69a","oa-sani_return_temp":"\ue69b","oa-sani_pump":"\ue69c","oa-sani_irrigation":"\ue69d","oa-sani_heating_temp":"\ue69e","oa-sani_heating_manual":"\ue69f","oa-sani_heating_automatic":"\ue6a0","oa-sani_heating":"\ue6a1","oa-sani_garden_pump":"\ue6a2","oa-sani_floor_heating":"\ue6a3","oa-sani_earth_source_heat_pump":"\ue6a4","oa-sani_domestic_waterworks":"\ue6a5","oa-sani_buffer_temp_up":"\ue6a6","oa-sani_buffer_temp_down":"\ue6a7","oa-sani_buffer_temp_all":"\ue6a8","oa-sani_boiler_temp":"\ue6a9","oa-phone_ring_out":"\ue6aa","oa-phone_ring_in":"\ue6ab","oa-phone_ring":"\ue6ac","oa-phone_missed_out":"\ue6ad","oa-phone_missed_in":"\ue6ae","oa-phone_dial":"\ue6af","oa-phone_call_out":"\ue6b0","oa-phone_call_in":"\ue6b1","oa-phone_call_end_out":"\ue6b2","oa-phone_call_end_in":"\ue6b3","oa-phone_call_end":"\ue6b4","oa-phone_call":"\ue6b5","oa-phone_answersing":"\ue6b6","oa-message_tendency_upward":"\ue6b7","oa-message_tendency_steady":"\ue6b8","oa-message_tendency_downward":"\ue6b9","oa-message_socket_on_off":"\ue6ba","oa-message_socket_ch_3":"\ue6bb","oa-message_socket_ch":"\ue6bc","oa-message_socket":"\ue6bd","oa-message_service":"\ue6be","oa-message_presence_disabled":"\ue6bf","oa-message_presence":"\ue6c0","oa-message_ok":"\ue6c1","oa-message_medicine":"\ue6c2","oa-message_mail_open":"\ue6c3","oa-message_mail":"\ue6c4","oa-message_light_intensity":"\ue6c5","oa-message_garbage":"\ue6c6","oa-message_attention":"\ue6c7","oa-measure_water_meter":"\ue6c8","oa-measure_voltage":"\ue6c9","oa-measure_power_meter":"\ue6ca","oa-measure_power":"\ue6cb","oa-measure_photovoltaic_inst":"\ue6cc","oa-measure_current":"\ue6cd","oa-measure_battery_100":"\ue6ce","oa-measure_battery_75":"\ue6cf","oa-measure_battery_50":"\ue6d0","oa-measure_battery_25":"\ue6d1","oa-measure_battery_0":"\ue6d2","oa-light_wire_system_2":"\ue6d3","oa-light_wire_system_1":"\ue6d4","oa-light_wall_3":"\ue6d5","oa-light_wall_2":"\ue6d6","oa-light_wall_1":"\ue6d7","oa-light_uplight":"\ue6d8","oa-light_stairs":"\ue6d9","oa-light_pendant_light_round":"\ue6da","oa-light_pendant_light":"\ue6db","oa-light_party":"\ue6dc","oa-light_outdoor":"\ue6dd","oa-light_office_desk":"\ue6de","oa-light_office":"\ue6df","oa-light_mirror":"\ue6e0","oa-light_light_dim_100":"\ue6e1","oa-light_light_dim_90":"\ue6e2","oa-light_light_dim_80":"\ue6e3","oa-light_light_dim_70":"\ue6e4","oa-light_light_dim_60":"\ue6e5","oa-light_light_dim_50":"\ue6e6","oa-light_light_dim_40":"\ue6e7","oa-light_light_dim_30":"\ue6e8","oa-light_light_dim_20":"\ue6e9","oa-light_light_dim_10":"\ue6ea","oa-light_light_dim_00":"\ue6eb","oa-light_light":"\ue6ec","oa-light_led_stripe_rgb":"\ue6ed","oa-light_led_stripe":"\ue6ee","oa-light_led":"\ue6ef","oa-light_floor_lamp":"\ue6f0","oa-light_fairy_lights":"\ue6f1","oa-light_downlight":"\ue6f2","oa-light_dinner_table":"\ue6f3","oa-light_diffused":"\ue6f4","oa-light_control":"\ue6f5","oa-light_ceiling_light":"\ue6f6","oa-light_cabinet":"\ue6f7","oa-it_wireless_dcf77":"\ue6f8","oa-it_wifi":"\ue6f9","oa-it_television":"\ue6fa","oa-it_telephone":"\ue6fb","oa-it_smartphone":"\ue6fc","oa-it_server":"\ue6fd","oa-it_satellite_dish_heating":"\ue6fe","oa-it_satellite_dish":"\ue6ff","oa-it_router":"\ue700","oa-it_remote":"\ue701","oa-it_radio":"\ue702","oa-it_pc":"\ue703","oa-it_network":"\ue704","oa-it_net":"\ue705","oa-it_nas":"\ue706","oa-it_internet":"\ue707","oa-it_fax":"\ue708","oa-it_camera":"\ue709","oa-fts_window_roof_shutter":"\ue70a","oa-fts_window_roof_open_2":"\ue70b","oa-fts_window_roof_open_1":"\ue70c","oa-fts_window_roof":"\ue70d","oa-fts_window_louvre_open":"\ue70e","oa-fts_window_louvre":"\ue70f","oa-fts_window_2w_tilt_r":"\ue710","oa-fts_window_2w_tilt_lr":"\ue711","oa-fts_window_2w_tilt_l_open_r":"\ue712","oa-fts_window_2w_tilt_l":"\ue713","oa-fts_window_2w_tilt":"\ue714","oa-fts_window_2w_open_r":"\ue715","oa-fts_window_2w_open_lr":"\ue716","oa-fts_window_2w_open_l_tilt_r":"\ue717","oa-fts_window_2w_open_l":"\ue718","oa-fts_window_2w_open":"\ue719","oa-fts_window_2w":"\ue71a","oa-fts_window_1w_tilt":"\ue71b","oa-fts_window_1w_open":"\ue71c","oa-fts_window_1w":"\ue71d","oa-fts_sunblind":"\ue71e","oa-fts_sliding_gate":"\ue71f","oa-fts_shutter_up":"\ue720","oa-fts_shutter_manual":"\ue721","oa-fts_shutter_down":"\ue722","oa-fts_shutter_automatic":"\ue723","oa-fts_shutter_100":"\ue724","oa-fts_shutter_90":"\ue725","oa-fts_shutter_80":"\ue726","oa-fts_shutter_70":"\ue727","oa-fts_shutter_60":"\ue728","oa-fts_shutter_50":"\ue729","oa-fts_shutter_40":"\ue72a","oa-fts_shutter_30":"\ue72b","oa-fts_shutter_20":"\ue72c","oa-fts_shutter_10":"\ue72d","oa-fts_shutter":"\ue72e","oa-fts_light_dome_open":"\ue72f","oa-fts_light_dome":"\ue730","oa-fts_garage_door_100":"\ue731","oa-fts_garage_door_90":"\ue732","oa-fts_garage_door_80":"\ue733","oa-fts_garage_door_70":"\ue734","oa-fts_garage_door_60":"\ue735","oa-fts_garage_door_50":"\ue736","oa-fts_garage_door_40":"\ue737","oa-fts_garage_door_30":"\ue738","oa-fts_garage_door_20":"\ue739","oa-fts_garage_door_10":"\ue73a","oa-fts_garage":"\ue73b","oa-fts_door_slide_open_m":"\ue73c","oa-fts_door_slide_open":"\ue73d","oa-fts_door_slide_m":"\ue73e","oa-fts_door_slide_2w_open_r":"\ue73f","oa-fts_door_slide_2w_open_lr":"\ue740","oa-fts_door_slide_2w_open_l":"\ue741","oa-fts_door_slide_2w":"\ue742","oa-fts_door_slide":"\ue743","oa-fts_door_open":"\ue744","oa-fts_door":"\ue745","oa-fts_blade_z_sun":"\ue746","oa-fts_blade_z":"\ue747","oa-fts_blade_s_sun":"\ue748","oa-fts_blade_s":"\ue749","oa-fts_blade_arc_sun":"\ue74a","oa-fts_blade_arc_close_100":"\ue74b","oa-fts_blade_arc_close_50":"\ue74c","oa-fts_blade_arc_close_00":"\ue74d","oa-fts_blade_arc":"\ue74e","oa-edit_sort":"\ue74f","oa-edit_settings":"\ue750","oa-edit_save":"\ue751","oa-edit_paste":"\ue752","oa-edit_open":"\ue753","oa-edit_expand":"\ue754","oa-edit_delete":"\ue755","oa-edit_cut":"\ue756","oa-edit_copy":"\ue757","oa-edit_collapse":"\ue758","oa-control_zoom_out":"\ue759","oa-control_zoom_in":"\ue75a","oa-control_x":"\ue75b","oa-control_standby":"\ue75c","oa-control_return":"\ue75d","oa-control_reboot":"\ue75e","oa-control_plus":"\ue75f","oa-control_outside_on_off":"\ue760","oa-control_on_off":"\ue761","oa-control_minus":"\ue762","oa-control_home":"\ue763","oa-control_centr_arrow_up_right":"\ue764","oa-control_centr_arrow_up_left":"\ue765","oa-control_centr_arrow_up":"\ue766","oa-control_centr_arrow_right":"\ue767","oa-control_centr_arrow_left":"\ue768","oa-control_centr_arrow_down_right":"\ue769","oa-control_centr_arrow_down_left":"\ue76a","oa-control_centr_arrow_down":"\ue76b","oa-control_building_s_og":"\ue76c","oa-control_building_s_kg":"\ue76d","oa-control_building_s_eg":"\ue76e","oa-control_building_s_dg":"\ue76f","oa-control_building_s_all":"\ue770","oa-control_building_outside":"\ue771","oa-control_building_og":"\ue772","oa-control_building_modern_s_okg_og":"\ue773","oa-control_building_modern_s_okg_eg":"\ue774","oa-control_building_modern_s_okg_dg":"\ue775","oa-control_building_modern_s_okg_all":"\ue776","oa-control_building_modern_s_og":"\ue777","oa-control_building_modern_s_kg":"\ue778","oa-control_building_modern_s_eg":"\ue779","oa-control_building_modern_s_dg":"\ue77a","oa-control_building_modern_s_all":"\ue77b","oa-control_building_modern_s_2og_og2":"\ue77c","oa-control_building_modern_s_2og_og1":"\ue77d","oa-control_building_modern_s_2og_kg":"\ue77e","oa-control_building_modern_s_2og_eg":"\ue77f","oa-control_building_modern_s_2og_dg":"\ue780","oa-control_building_modern_s_2og_all":"\ue781","oa-control_building_kg":"\ue782","oa-control_building_filled":"\ue783","oa-control_building_empty":"\ue784","oa-control_building_eg":"\ue785","oa-control_building_dg":"\ue786","oa-control_building_control":"\ue787","oa-control_building_all":"\ue788","oa-control_building_2_s_kg":"\ue789","oa-control_building_2_s_eg":"\ue78a","oa-control_building_2_s_dg":"\ue78b","oa-control_building_2_s_all":"\ue78c","oa-control_arrow_upward":"\ue78d","oa-control_arrow_up_right":"\ue78e","oa-control_arrow_up_left":"\ue78f","oa-control_arrow_up":"\ue790","oa-control_arrow_turn_right":"\ue791","oa-control_arrow_turn_left":"\ue792","oa-control_arrow_rightward":"\ue793","oa-control_arrow_right":"\ue794","oa-control_arrow_leftward":"\ue795","oa-control_arrow_left":"\ue796","oa-control_arrow_downward":"\ue797","oa-control_arrow_down_right":"\ue798","oa-control_arrow_down_left":"\ue799","oa-control_arrow_down":"\ue79a","oa-control_all_on_off":"\ue79b","oa-control_4":"\ue79c","oa-control_3":"\ue79d","oa-control_2":"\ue79e","oa-control_1":"\ue79f","oa-audio_volume_mute":"\ue7a0","oa-audio_volume_mid":"\ue7a1","oa-audio_volume_low":"\ue7a2","oa-audio_volume_high":"\ue7a3","oa-audio_stop":"\ue7a4","oa-audio_sound":"\ue7a5","oa-audio_shuffle":"\ue7a6","oa-audio_rew":"\ue7a7","oa-audio_repeat":"\ue7a8","oa-audio_rec":"\ue7a9","oa-audio_playlist":"\ue7aa","oa-audio_play":"\ue7ab","oa-audio_pause":"\ue7ac","oa-audio_mic_mute":"\ue7ad","oa-audio_mic":"\ue7ae","oa-audio_loudness":"\ue7af","oa-audio_headphone":"\ue7b0","oa-audio_ff":"\ue7b1","oa-audio_fade":"\ue7b2","oa-audio_eq":"\ue7b3","oa-audio_eject":"\ue7b4","oa-audio_audio":"\ue7b5"}; var FONT_FHEMSVG = {"fs-user_unknown":"\ue600","fs-usb_stick":"\ue601","fs-usb":"\ue602","fs-unlock":"\ue603","fs-unknown":"\ue604","fs-temperature_humidity":"\ue605","fs-taster_ch6_6":"\ue606","fs-taster_ch6_5":"\ue607","fs-taster_ch6_4":"\ue608","fs-taster_ch6_3":"\ue609","fs-taster_ch6_2":"\ue60a","fs-taster_ch6_1":"\ue60b","fs-taster_ch_aus_rot .path1":"\ue60c","fs-taster_ch_aus_rot .path2":"\ue60d","fs-taster_ch_aus_rot .path3":"\ue60e","fs-taster_ch_aus_rot .path4":"\ue60f","fs-taster_ch_aus_rot .path5":"\ue610","fs-taster_ch_aus_rot .path6":"\ue611","fs-taster_ch_an_gruen .path1":"\ue612","fs-taster_ch_an_gruen .path2":"\ue613","fs-taster_ch_an_gruen .path3":"\ue614","fs-taster_ch_an_gruen .path4":"\ue615","fs-taster_ch_an_gruen .path5":"\ue616","fs-taster_ch_2":"\ue617","fs-taster_ch_1":"\ue618","fs-taster_ch":"\ue619","fs-taster":"\ue61a","fs-system_fhem_update":"\ue61b","fs-system_fhem_reboot":"\ue61c","fs-system_fhem":"\ue61d","fs-system_backup":"\ue61e","fs-socket_timer":"\ue61f","fs-security_password":"\ue620","fs-security":"\ue621","fs-sdcard":"\ue622","fs-scc_868":"\ue623","fs-sani_heating_timer":"\ue624","fs-sani_heating_level_100":"\ue625","fs-sani_heating_level_90":"\ue626","fs-sani_heating_level_80":"\ue627","fs-sani_heating_level_70":"\ue628","fs-sani_heating_level_60":"\ue629","fs-sani_heating_level_50":"\ue62a","fs-sani_heating_level_40":"\ue62b","fs-sani_heating_level_30":"\ue62c","fs-sani_heating_level_20":"\ue62d","fs-sani_heating_level_10":"\ue62e","fs-sani_heating_level_0":"\ue62f","fs-sani_heating_calendar":"\ue630","fs-sani_heating_boost":"\ue631","fs-sani_floor_heating_off":"\ue632","fs-sani_floor_heating_neutral":"\ue633","fs-RPi .path1":"\ue634","fs-RPi .path2":"\ue635","fs-RPi .path3":"\ue636","fs-RPi .path4":"\ue637","fs-RPi .path5":"\ue638","fs-RPi .path6":"\ue639","fs-RPi .path7":"\ue63a","fs-RPi .path8":"\ue63b","fs-RPi .path9":"\ue63c","fs-RPi .path10":"\ue63d","fs-RPi .path11":"\ue63e","fs-RPi .path12":"\ue63f","fs-RPi .path13":"\ue640","fs-RPi .path14":"\ue641","fs-RPi .path15":"\ue642","fs-RPi .path16":"\ue643","fs-RPi .path17":"\ue644","fs-RPi .path18":"\ue645","fs-RPi .path19":"\ue646","fs-RPi .path20":"\ue647","fs-RPi .path21":"\ue648","fs-remote_control":"\ue649","fs-refresh":"\ue64a","fs-recycling":"\ue64b","fs-rc_YELLOW .path1":"\ue64c","fs-rc_YELLOW .path2":"\ue64d","fs-rc_WEB":"\ue64e","fs-rc_VOLUP":"\ue64f","fs-rc_VOLPLUS":"\ue650","fs-rc_VOLMINUS":"\ue651","fs-rc_VOLDOWN":"\ue652","fs-rc_VIDEO":"\ue653","fs-rc_USB":"\ue654","fs-rc_UP":"\ue655","fs-rc_TVstop":"\ue656","fs-rc_TV":"\ue657","fs-rc_TEXT":"\ue658","fs-rc_templatebutton":"\ue659","fs-rc_SUB":"\ue65a","fs-rc_STOP":"\ue65b","fs-rc_SHUFFLE":"\ue65c","fs-rc_SETUP":"\ue65d","fs-rc_SEARCH":"\ue65e","fs-rc_RIGHT":"\ue65f","fs-rc_REWred":"\ue660","fs-rc_REW":"\ue661","fs-rc_REPEAT":"\ue662","fs-rc_RED .path1":"\ue663","fs-rc_RED .path2":"\ue664","fs-rc_REC .path1":"\ue665","fs-rc_REC .path2":"\ue666","fs-rc_RADIOred":"\ue667","fs-rc_RADIO":"\ue668","fs-rc_PREVIOUS":"\ue669","fs-rc_POWER":"\ue66a","fs-rc_PLUS":"\ue66b","fs-rc_PLAYgreen":"\ue66c","fs-rc_PLAY":"\ue66d","fs-rc_PAUSEyellow":"\ue66e","fs-rc_PAUSE":"\ue66f","fs-rc_OPTIONS":"\ue670","fs-rc_OK":"\ue671","fs-rc_NEXT":"\ue672","fs-rc_MUTE":"\ue673","fs-rc_MINUS":"\ue674","fs-rc_MENU":"\ue675","fs-rc_MEDIAMENU":"\ue676","fs-rc_LEFT":"\ue677","fs-rc_INFO":"\ue678","fs-rc_HOME":"\ue679","fs-rc_HELP":"\ue67a","fs-rc_HDMI":"\ue67b","fs-rc_GREEN .path1":"\ue67c","fs-rc_GREEN .path2":"\ue67d","fs-rc_FFblue":"\ue67e","fs-rc_FF":"\ue67f","fs-rc_EXIT":"\ue680","fs-rc_EPG":"\ue681","fs-rc_EJECT":"\ue682","fs-rc_DOWN":"\ue683","fs-rc_dot":"\ue684","fs-rc_BLUE .path1":"\ue685","fs-rc_BLUE .path2":"\ue686","fs-rc_BLANK":"\ue687","fs-rc_BACK":"\ue688","fs-rc_AV":"\ue689","fs-rc_AUDIO":"\ue68a","fs-rc_9":"\ue68b","fs-rc_8":"\ue68c","fs-rc_7":"\ue68d","fs-rc_6":"\ue68e","fs-rc_5":"\ue68f","fs-rc_4":"\ue690","fs-rc_3":"\ue691","fs-rc_2":"\ue692","fs-rc_1":"\ue693","fs-rc_0":"\ue694","fs-people_sensor":"\ue695","fs-outside_socket":"\ue696","fs-motion_detector":"\ue697","fs-message_socket_unknown":"\ue698","fs-message_socket_on2":"\ue699","fs-message_socket_off2":"\ue69a","fs-message_socket_off":"\ue69b","fs-message_socket_enabled":"\ue69c","fs-message_socket_disabled":"\ue69d","fs-max_wandthermostat":"\ue69e","fs-max_heizungsthermostat":"\ue69f","fs-lock":"\ue6a0","fs-light_toggle":"\ue6a1","fs-light_question .path1":"\ue6a2","fs-light_question .path2":"\ue6a3","fs-light_question .path3":"\ue6a4","fs-light_question .path4":"\ue6a5","fs-light_question .path5":"\ue6a6","fs-light_question .path6":"\ue6a7","fs-light_outdoor":"\ue6a8","fs-light_on-for-timer":"\ue6a9","fs-light_off-for-timer":"\ue6aa","fs-light_exclamation .path1":"\ue6ab","fs-light_exclamation .path2":"\ue6ac","fs-light_exclamation .path3":"\ue6ad","fs-light_exclamation .path4":"\ue6ae","fs-light_exclamation .path5":"\ue6af","fs-light_exclamation .path6":"\ue6b0","fs-light_dim_up":"\ue6b1","fs-light_dim_down":"\ue6b2","fs-light_ceiling_off":"\ue6b3","fs-light_ceiling":"\ue6b4","fs-lan_rs485":"\ue6b5","fs-it_remote_folder .path1":"\ue6b6","fs-it_remote_folder .path2":"\ue6b7","fs-it_remote_folder .path3":"\ue6b8","fs-it_remote_folder .path4":"\ue6b9","fs-it_remote_folder .path5":"\ue6ba","fs-it_remote_folder .path6":"\ue6bb","fs-it_remote_folder .path7":"\ue6bc","fs-it_remote_folder .path8":"\ue6bd","fs-it_remote_folder .path9":"\ue6be","fs-it_remote_folder .path10":"\ue6bf","fs-it_remote_folder .path11":"\ue6c0","fs-it_remote_folder .path12":"\ue6c1","fs-it_remote_folder .path13":"\ue6c2","fs-it_remote_folder .path14":"\ue6c3","fs-it_remote_folder .path15":"\ue6c4","fs-it_remote_folder .path16":"\ue6c5","fs-it_remote_folder .path17":"\ue6c6","fs-it_remote_folder .path18":"\ue6c7","fs-it_remote_folder .path19":"\ue6c8","fs-it_remote_folder .path20":"\ue6c9","fs-it_remote_folder .path21":"\ue6ca","fs-it_i-net":"\ue6cb","fs-it_hue_bridge .path1":"\ue6cc","fs-it_hue_bridge .path2":"\ue6cd","fs-it_hue_bridge .path3":"\ue6ce","fs-it_hue_bridge .path4":"\ue6cf","fs-it_hue_bridge .path5":"\ue6d0","fs-it_hue_bridge .path6":"\ue6d1","fs-it_hue_bridge .path7":"\ue6d2","fs-it_hue_bridge .path8":"\ue6d3","fs-it_hue_bridge .path9":"\ue6d4","fs-it_hue_bridge .path10":"\ue6d5","fs-it_hue_bridge .path11":"\ue6d6","fs-it_hue_bridge .path12":"\ue6d7","fs-it_hue_bridge .path13":"\ue6d8","fs-it_hue_bridge .path14":"\ue6d9","fs-it_hue_bridge .path15":"\ue6da","fs-it_hue_bridge .path16":"\ue6db","fs-it_hue_bridge .path17":"\ue6dc","fs-it_hue_bridge .path18":"\ue6dd","fs-it_hue_bridge .path19":"\ue6de","fs-it_hue_bridge .path20":"\ue6df","fs-it_hue_bridge .path21":"\ue6e0","fs-it_hue_bridge .path22":"\ue6e1","fs-it_hue_bridge .path23":"\ue6e2","fs-IR":"\ue6e3","fs-Icon_Fisch":"\ue6e4","fs-humidity":"\ue6e5","fs-hue_bridge .path1":"\ue6e6","fs-hue_bridge .path2":"\ue6e7","fs-hue_bridge .path3":"\ue6e8","fs-hue_bridge .path4":"\ue6e9","fs-hue_bridge .path5":"\ue6ea","fs-hue_bridge .path6":"\ue6eb","fs-hue_bridge .path7":"\ue6ec","fs-hue_bridge .path8":"\ue6ed","fs-hue_bridge .path9":"\ue6ee","fs-hue_bridge .path10":"\ue6ef","fs-hue_bridge .path11":"\ue6f0","fs-hue_bridge .path12":"\ue6f1","fs-hue_bridge .path13":"\ue6f2","fs-hue_bridge .path14":"\ue6f3","fs-hue_bridge .path15":"\ue6f4","fs-hue_bridge .path16":"\ue6f5","fs-hue_bridge .path17":"\ue6f6","fs-hue_bridge .path18":"\ue6f7","fs-hue_bridge .path19":"\ue6f8","fs-hue_bridge .path20":"\ue6f9","fs-hue_bridge .path21":"\ue6fa","fs-hue_bridge .path22":"\ue6fb","fs-hue_bridge .path23":"\ue6fc","fs-hourglass":"\ue6fd","fs-hm-tc-it-wm-w-eu":"\ue6fe","fs-hm-dis-wm55":"\ue6ff","fs-hm-cc-rt-dn":"\ue700","fs-hm_lan":"\ue701","fs-hm_keymatic":"\ue702","fs-hm_ccu":"\ue703","fs-general_ok":"\ue704","fs-general_low":"\ue705","fs-general_aus_fuer_zeit":"\ue706","fs-general_aus":"\ue707","fs-general_an_fuer_zeit":"\ue708","fs-general_an":"\ue709","fs-garden_socket":"\ue70a","fs-fts_window_1wbb_open":"\ue70b","fs-fts_shutter_updown":"\ue70c","fs-fts_door_tilt":"\ue70d","fs-fts_door_right_open":"\ue70e","fs-fts_door_right":"\ue70f","fs-frost":"\ue710","fs-floor":"\ue711","fs-dustbin":"\ue712","fs-dreambox":"\ue713","fs-dog_silhouette":"\ue714","fs-DIN_rail_housing .path1":"\ue715","fs-DIN_rail_housing .path2":"\ue716","fs-DIN_rail_housing .path3":"\ue717","fs-DIN_rail_housing .path4":"\ue718","fs-DIN_rail_housing .path5":"\ue719","fs-DIN_rail_housing .path6":"\ue71a","fs-DIN_rail_housing .path7":"\ue71b","fs-DIN_rail_housing .path8":"\ue71c","fs-DIN_rail_housing .path9":"\ue71d","fs-DIN_rail_housing .path10":"\ue71e","fs-DIN_rail_housing .path11":"\ue71f","fs-DIN_rail_housing .path12":"\ue720","fs-DIN_rail_housing .path13":"\ue721","fs-DIN_rail_housing .path14":"\ue722","fs-DIN_rail_housing .path15":"\ue723","fs-DIN_rail_housing .path16":"\ue724","fs-DIN_rail_housing .path17":"\ue725","fs-DIN_rail_housing .path18":"\ue726","fs-DIN_rail_housing .path19":"\ue727","fs-DIN_rail_housing .path20":"\ue728","fs-DIN_rail_housing .path21":"\ue729","fs-DIN_rail_housing .path22":"\ue72a","fs-DIN_rail_housing .path23":"\ue72b","fs-DIN_rail_housing .path24":"\ue72c","fs-DIN_rail_housing .path25":"\ue72d","fs-DIN_rail_housing .path26":"\ue72e","fs-DIN_rail_housing .path27":"\ue72f","fs-DIN_rail_housing .path28":"\ue730","fs-DIN_rail_housing .path29":"\ue731","fs-DIN_rail_housing .path30":"\ue732","fs-DIN_rail_housing .path31":"\ue733","fs-DIN_rail_housing .path32":"\ue734","fs-DIN_rail_housing .path33":"\ue735","fs-DIN_rail_housing .path34":"\ue736","fs-DIN_rail_housing .path35":"\ue737","fs-DIN_rail_housing .path36":"\ue738","fs-DIN_rail_housing .path37":"\ue739","fs-DIN_rail_housing .path38":"\ue73a","fs-DIN_rail_housing .path39":"\ue73b","fs-DIN_rail_housing .path40":"\ue73c","fs-DIN_rail_housing .path41":"\ue73d","fs-DIN_rail_housing .path42":"\ue73e","fs-DIN_rail_housing .path43":"\ue73f","fs-DIN_rail_housing .path44":"\ue740","fs-DIN_rail_housing .path45":"\ue741","fs-DIN_rail_housing .path46":"\ue742","fs-DIN_rail_housing .path47":"\ue743","fs-DIN_rail_housing .path48":"\ue744","fs-DIN_rail_housing .path49":"\ue745","fs-day_night":"\ue746","fs-cul_usb":"\ue747","fs-cul_cul":"\ue748","fs-cul_868":"\ue749","fs-cul":"\ue74a","fs-christmas_tree":"\ue74b","fs-building_security":"\ue74c","fs-building_outside":"\ue74d","fs-building_carport_socket":"\ue74e","fs-building_carport_light":"\ue74f","fs-building_carport":"\ue750","fs-bluetooth":"\ue751","fs-batterie":"\ue752","fs-bag":"\ue753","fs-ampel_rot .path1":"\ue754","fs-ampel_rot .path2":"\ue755","fs-ampel_gruen .path1":"\ue756","fs-ampel_gruen .path2":"\ue757","fs-ampel_gelb .path1":"\ue758","fs-ampel_gelb .path2":"\ue759","fs-ampel_aus":"\ue75a","fs-alarm_system_password":"\ue75b","fs-access_keypad_2":"\ue75c","fs-access_keypad_1":"\ue75d"}; //helper code for retrieving glyph information for FONT_AWESOME, not needed for normal operation - /*var faCheatsLoaded = false; if (faPage === undefined) { @@ -313,11 +299,11 @@ var widget_chart = { case 'maxvalue_sec': case 'minvalue_sec': $.each(values,function(i,v){ - elem.data(val[0]+'#internal#'+i,v); // add additional data value with extension '#internal' (need to allow updates) - if (!$.isArray(v) && elem.isDeviceReading(val[0]+'#internal#'+i)) { - obj.addReading(elem, val[0]+'#internal#'+i); // trace new reading with extension '#internal##num' + elem.data(val[0]+'_internal_'+i,v); // add additional data value with extension '_internal' (need to allow updates) + if (!$.isArray(v) && elem.isDeviceReading(val[0]+'_internal_'+i)) { + obj.addReading(elem, val[0]+'_internal_'+i); // trace new reading with extension '_internal_#num' } else { // no device:reading setting, remove additional data value - elem.removeData(val[0]+'#internal#'+i); + elem.removeData(val[0]+'_internal_'+i); } }); break; @@ -328,18 +314,18 @@ var widget_chart = { var drary = v.split(':'); isValidDeviceReading = ftui.deviceStates[drary[0]]!==undefined; } - elem.data(val[0]+'#internal#'+i,v); // add additional data value with extension '#internal' (need to allow updates) - if (isValidDeviceReading && elem.isDeviceReading(val[0]+'#internal#'+i)) { - obj.addReading(elem, val[0]+'#internal#'+i); // trace new reading with extension '#internal##num' + elem.data(val[0]+'_internal_'+i,v); // add additional data value with extension '_internal' (need to allow updates) + if (isValidDeviceReading && elem.isDeviceReading(val[0]+'_internal_'+i)) { + obj.addReading(elem, val[0]+'_internal_'+i); // trace new reading with extension '_internal_#num' } else { // no device:reading setting, remove additional data value - elem.removeData(val[0]+'#internal#'+i); + elem.removeData(val[0]+'_internal_'+i); } }); break; } - } else if (val[0].search(/#internal#/) > -1) { - var index = parseInt(val[0].split('#')[val[0].split('#').length-1]); - var key = val[0].split('#')[0]; + } else if (val[0].search(/_internal_/) > -1) { + var index = parseInt(val[0].split('_')[val[0].split('_').length-1]); + var key = val[0].split('_')[0]; switch(key) { case 'style': case 'maxvalue': @@ -353,7 +339,7 @@ var widget_chart = { if ((index < values.length) && (values[index] != newval)) { values[index] = newval; elem.data(key,values); - if (data.done && data.baseDone) widget_chart.refresh(elem,'start'); + if (data.done) widget_chart.refresh(elem,'start'); } } break; @@ -368,8 +354,8 @@ var widget_chart = { var mingr = (style&&style.length&&style[0]=='fill')?Math.min(min,mingraph):mingraph; var maxgr = maxgraph; var scale = (max-min)/(maxgr-mingr); - var y1 = (mingr===Infinity||maxgr===-Infinity)?0:0-(max-maxgr)/(max-min)*scale*100; - var y2 = (mingr===Infinity||maxgr===-Infinity)?100:100+(mingr-min)/(max-min)*scale*100; + var y1 = 0-(max-maxgr)/(max-min)*scale*100; + var y2 = 100+(mingr-min)/(max-min)*scale*100; var grID = instance+'_'+(k+1); // gradient ID, assuming that there are not more than 10000 instances of chart widgets per page. var styledef, styledeftext; var newdef = ''; @@ -449,8 +435,6 @@ var widget_chart = { return {stroke:strk, dash:dashArray}; }, getBrowserCaps: function() { // helper function to find out browser capabilities - if (widget_chart.gBCaps) return widget_chart.gBCaps; - if (!window.getComputedStyle) { return false; } @@ -494,11 +478,9 @@ var widget_chart = { } } - widget_chart.gBCaps = {'result':result,'svg_transform_needed':svg_transform_needed,'doSVGTransformCorrection':doSVGTransformCorrection,'prefix':pref.replace('transform','')}; - - return widget_chart.gBCaps; + return ({'result':result,'svg_transform_needed':svg_transform_needed,'doSVGTransformCorrection':doSVGTransformCorrection,'prefix':pref.replace('transform','')}); }, - getTransformedPoint: function(data,svgbase,point,special) { // helper function to transform 3D point in 2D view + getTransformedPoint: function(data,svgbase,point) { // helper function to transform 3D point in 2D view //if (!data.DDD.Active) return point; var left = (data.getGraphLeft()); var width = data.graphWidth/100*data.basewidth; @@ -516,7 +498,7 @@ var widget_chart = { ''); var attrval = {style:data.DDD.prefix+'transform:'+data.DDD.String.Scale+'; position:absolute'}; - if (!special) dummy.find('div.baseforDDD').attr(attrval); + dummy.find('div.baseforDDD').attr(attrval); attrval = {style:data.DDD.String.Rot+'; '+data.DDD.String.Trans(point.z,0,data.DDD,data.xStrTO,data.yStrTO)+'; position:absolute'}; dummy.find('div.baseRotation').attr(attrval); attrval = {style:'; left:'+left+'px; width:'+width+'px; top:'+top+'px; height:'+height+'px; position:absolute'}; @@ -684,7 +666,6 @@ var widget_chart = { var cx = {p1:[], p2:[]}; var cy = {p1:[], p2:[]}; - var disconnected_inner, disconnected_outer; for (var i=0, leni=n-1; i0?ptype.indexOf('_proxy'):ptype.length)).split('-'); - var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; - var start = subtype.search('start')>-1?true:false; - var end = subtype.search('end')>-1?true:false; - var type = ptc[0]; - switch (type) { + switch (ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))) { case 'lines': first = true; for (i=0,l=arg.length;i0 && (arg[i-1][5] && arg[i-1][5]==true))) { - res.push(" L " + arg[i][0] + "," + arg[i][1] + " Q "); - } else { - res.push(cx.p2[i] + ", " + cy.p2[i] + ", " + arg[i+1][0] + ", " + arg[i+1][1]+ " "); - } - } + res.push(cx.p2[i] + ", " + cy.p2[i] + ", " + arg[i+1] + " "); } } if (!proxy) res.push("L" + arg[arg.length-1][0] + "," + (closed?min + " Z":arg[arg.length-1][1])); @@ -1119,27 +1027,13 @@ var widget_chart = { case 'quadraticSmooth': first = true; for (i=0,l=arg.length-1;i0 && (arg[i-1][5] && arg[i-1][5]==true))) { - res.push(arg[i][0] + ", " + arg[i][1] + " L "); - res.push(arg[i][0] + ", " + arg[i][1] + " T "); - res.push(((arg[i][0]+arg[i+1][0])/2) + ", " + ((arg[i][1]+arg[i+1][1])/2) + " "); - } else { - res.push(((arg[i][0]+arg[i+1][0])/2) + ", " + ((arg[i][1]+arg[i+1][1])/2) + " "); - } - } + res.push(((arg[i][0]+arg[i+1][0])/2) + ", " + ((arg[i][1]+arg[i+1][1])/2) + " "); } } res.push("L" + arg[arg.length-1][0] + "," + (closed?min + " Z":arg[arg.length-1][1])); @@ -1249,17 +1143,6 @@ var widget_chart = { if ($.isArray(array)) {rVal = array[Math.min(i,array.length-1)];} else if (array !== undefined) {rVal = array;} else {rVal = defVal;} return rVal; }, - getDynamicStyle: function(style) { - var ret = ''; - if ($.isArray(style) && style[0].search(/graphbase/)>=0) { - $.each(style, function(index, value) { - if (value.search(/style/)>=0) ret = value.search(':')>=0?value.split(':')[1]:''; - }); - return ret; - } else { - return style; - } - }, getArrayLength: function(array) { var n=0; if ($.isArray(array)) { @@ -1293,7 +1176,6 @@ var widget_chart = { nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.legend)); nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.style)); nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.graphsshown)); - nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.cursorshown)); return nGraphs; }, getDateTimeNumberString: function(date,format) { // generate Date/Time String according to format given @@ -1494,9 +1376,7 @@ var widget_chart = { case 'h': // number counts in hours if (!doRounding) { now = new Date(); - var hours = parseInt(dStr); - var minutes = (parseFloat(dStr) - hours)*60; - ddiff = widget_chart.dateDiff(new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0), new Date(now.getFullYear(),now.getMonth(),now.getDate(),hours,minutes,0,0), 'd'); + ddiff = widget_chart.dateDiff(new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0), new Date(now.getFullYear(),now.getMonth(),now.getDate(),parseFloat(dStr),0,0,0), 'd'); } else { ddiff = parseFloat(dStr)/24; if (!data.nofulldays) ddiff = parseInt(ddiff); @@ -1535,7 +1415,7 @@ var widget_chart = { } else { now = new Date(); ddiff = widget_chart.dateDiff(ds, new Date(now.getFullYear(),now.getMonth(),now.getDate(),-now.getTimezoneOffset()/60-now.stdTimezoneOffset()/60,0,0,0), 'd'); - if (!data.nofulldays) ddiff = parseInt(ddiff+(ddiff<0?-0.5:0.5)); + if (!data.nofulldays) ddiff = parseInt(ddiff); return ddiff; } }, @@ -1567,7 +1447,7 @@ var widget_chart = { } }, getFormattedText: function(txt) { // helper function to generate svg text element with html formatting possibilities - var outtext = String(txt); + var outtext = txt; outtext = outtext.replace(/\/g,''); outtext = outtext.replace(/\<\/i\>/g,''); @@ -1652,7 +1532,7 @@ var widget_chart = { data.title_object = widget_chart.getFormattedText(data.title_object); }, - roundXticks: function(round_in, x, xrange, startdate, asize) { // helper function to support correct xtick positions (rounded time values) + roundXticks: function(round_in, x, xrange, startdate) { // helper function to support correct xtick positions (rounded time values) var xret = x; var round; @@ -1686,19 +1566,15 @@ var widget_chart = { xret = parseInt(x/60/24+0.5)*60*24-xstart; // correct xret to number of minutes to closest day since start date/time break; case 'w': // rounding to weeks - if (asize == 7) { - var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped - } else if (asize == 3.5) { - var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()/2*60*24; // correction needed to be sure that hours inside full day are skipped - } - xret = parseInt(x/60/24/asize+0.5)*60*24*asize-xstart; // correct xret to number of minutes to closest first day of week since start date/time + var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped + xret = parseInt(x/60/24/7+0.5)*60*24*7-xstart; // correct xret to number of minutes to closest first day of week since start date/time break; case 'm': // rounding to months var xstart = startdate.getMinutes()+startdate.getHours()*60; // correction needed to be sure that hours inside full day are skipped - if (actdate.getDate()'; - return cp; - }, getClipSettings: function(cliprange_in) { var clipsettings = {}; @@ -1808,7 +1644,7 @@ var widget_chart = { } else if (timeformat.search('dd')>-1 || timeformat.search('ee')>-1) { // time text will contain days, in case of auto shift we have an offset of half a day diff = 24*60/2; } else if (timeformat.search('MM')>-1) { // time text will contain months, in case of auto shift we have an offset of half a month - diff = time.myGetDaysInMonth()*24*60/2; + diff = time.getDaysInMonth()*24*60/2; } else if (timeformat.search('yy')>-1) { // time text will contain years, in case of auto shift we have an offset of half a month diff = (time.isLeapYear()?366:365)*24*60/2; } @@ -1837,10 +1673,9 @@ var widget_chart = { var el = elem.find('[class*=yaxis_'+uaxis+'-'+ind+']'); // find object fitting to actual yaxis slot if (el.length > 0) { var axisPar = (uaxis!='secondary')?val.primary:val.secondary; - var xshift = (axisPar.yticks_prio)?0:((uaxis!='secondary')?-(data.unusedYAxesVisible?cyclicSum(data.textWidth_prim,index,ind-1):0):(data.unusedYAxesVisible?cyclicSum(data.textWidth_sec,index,ind-1):0)); - var opacity = data.unusedYAxesVisible?1:((uaxis!='secondary')?(ind==index?1:0):(ind==index?1:0)); + var xshift = (axisPar.yticks_prio)?0:((uaxis!='secondary')?-cyclicSum(data.textWidth_prim,index,ind-1):cyclicSum(data.textWidth_sec,index,ind-1)); var style = el.attr('style'); - style = data.unusedYAxesVisible?style.replace(/translateX\(.*\)/,'translateX('+xshift+'px)'):style.replace(/opacity\:.*\;/,'opacity:'+opacity+';'); + style = style.replace(/translateX\(.*\)/,'translateX('+xshift+'px)'); el.attr('style',style); } }); @@ -1854,136 +1689,17 @@ var widget_chart = { widget_chart.getBrowserCaps().doSVGTransformCorrection(elem); - }, - resetTime: function(event) { - var elem = $(event.delegateTarget); - var baseobject = elem.closest("[class^=basesvg]").parent(); - var data = baseobject.data(); - - if (data.iZoom === undefined || data.iZoom < 0) return; - - data.daysago_start_old = data.daysago_start; - data.daysago_end_old = data.daysago_end; - data.daysago_start = data.daysago_start_list[data.iZoom]; - data.daysago_end = data.daysago_end_list[data.iZoom]; - - data.iZoom--; - if (data.iZoom<0) data.iZoom = 0; - - baseobject.data(data); - - widget_chart.zoomTimeAnimated(baseobject,0,20,function(){ - if (data.iZoom == 0) data.nofulldays = data.nofulldays_old; - }); - - return; - }, - zoomTime: function(event) { - var elem = $(event.delegateTarget); - var baseobject = elem.closest("[class^=basesvg]").parent(); - var data = baseobject.data(); - var xleft = elem.data('xleft'); - var xright = elem.data('xright'); - - if (!xleft.getDate) return; - if (!xright.getDate) return; - - if (data.iZoom === undefined || data.iZoom < 0) { - data.iZoom = 0; - data.daysago_start_list = []; - data.daysago_end_list = []; - } else { - data.iZoom++; - } - - data.daysago_start_list[data.iZoom] = data.daysago_start; - data.daysago_start_old = data.daysago_start; - data.daysago_start = xleft.getDateStringFHEM(); - - data.daysago_end_list[data.iZoom] = data.daysago_end; - data.daysago_end_old = data.daysago_end; - data.daysago_end = xright.getDateStringFHEM(); - - data.nofulldays_old = data.nofulldays; - data.nofulldays = true; - - baseobject.data(data); - - widget_chart.zoomTimeAnimated(baseobject,0,20,function(){}); - - return; - }, - zoomTimeAnimated: function(elem,index,steps,callback) { - var data = elem.data(); - data.offsetX = 0; // offset for shifting arbitrarily due to mousemove and touchmove handling - data.scaleX = 1; // scale for scaling arbitrarily due to mousemove and touchmove handling - data.scaleDeltaX = 0; // scale for scaling arbitrarily due to mousemove and touchmove handling - - var days_start_old = widget_chart.getDaysAgo(data.daysago_start_old,data); - var days_start = widget_chart.getDaysAgo(data.daysago_start,data); - var days_end_old = widget_chart.getDaysAgo(data.daysago_end_old,data); - var days_end = widget_chart.getDaysAgo(data.daysago_end,data); - - - setTimeout(function() { - if (index <= steps) { - var ds = days_start_old*(steps-index)/steps+days_start*index/steps; - var de = days_end_old*(steps-index)/steps+days_end*index/steps; - var scl = (days_end_old - days_start_old)/(de - ds); - var dlt = -(days_start_old-ds)*scl*24*60; // new delta in minutes - dlt = dlt/data.xrange*data.basewidth*data.graphWidth/100-data.getGraphLeft()*(scl-1); // new delta in pixels - - widget_chart.shiftXContent(elem,data.offsetX,scl,dlt,data) - index++; - widget_chart.zoomTimeAnimated(elem,index,steps,callback); - } else { - widget_chart.refresh(elem,'start reset',0); - callback(); - var theDoc = (data.popup)?elem:$(document); - theDoc.find("[class^=basesvg]").each(function() { - if ($(this).parent().is(':visible')) { - if (($(this).parent().data().scrollgroup == data.scrollgroup) && data.scrollgroup!==undefined && data.instance!=$(this).parent().data().instance && $(this).parent().data().baseDone) { - $(this).parent().data('daysago_start',data.daysago_start); - $(this).parent().data('daysago_end',data.daysago_end); - widget_chart.refresh($(this).parent(),'start reset',0); - } - } - }); - } - },2000/steps); - }, showHideGridlines: function(event) { // helper function to prepare for toggle gridline display when axis string is clicked var elem = $(event.delegateTarget); var data = elem.closest("[class^=basesvg]").parent().data(); - var isPrimary = (elem.attr('class').search('primary')>-1); var AI = parseInt(elem.attr('class').replace(/.*-/,'')); $.each(data.yLimits, function(ind,val){ this.primary.yticks_prio = false; this.secondary.yticks_prio = false; }); - if (!data.unusedYAxesVisible) { // we need to find the next axis of the selected type and display this axis - var elaxes = elem.parent() - elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'')+"]").each(function() { - if ($(this).css('opacity') == 1) AI = parseInt($(this).attr('class').replace(/.*-/,'')) // find currently visible axis - }); - if (elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'-'+parseInt(AI+1))+"]").length > 0) { // there is an axis with higher AI, take this one - AI++; - } else { // no axis with higher index, take lowest one - var xs = elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'')+"]"); - var AI = Infinity; - xs.each(function() { - var aindex = parseInt($(this).attr('class').replace(/.*-/,'')); - if (aindex < AI) AI = aindex; - }); - if (AI == Infinity) AI = 0; - } - - if (AI > data.yLimits.length-1) AI = 0; - } - - if (isPrimary) { + if (elem.attr('class').search('primary')>-1) { data.yLimits[AI].primary.yticks_prio = true; } else { data.yLimits[AI].secondary.yticks_prio = true; @@ -1991,298 +1707,9 @@ var widget_chart = { widget_chart.doShowHideGridlines(data,elem.closest("[class^=basesvg]").parent()); }, - shiftXContent: function(_baseobject,_currentDistance,_currentScale,_currentScaleDelta,_data,noprop) { - if (!_data.DDD || !_data.graphArea) return; - var scale = _currentScale; - var offset = _currentScaleDelta; - var subobject = _baseobject.find("[id=baseforDDD]"); - _data.startXMove = _currentDistance; - _data.offsetX = _currentDistance; - _data.scaleX = _currentScale; - _data.scaleDeltaX = _currentScaleDelta; - - var transform2position = function(e,d,o) { - if (e.attr('x1')) { // line - if (e.attr('x1_orig') === undefined) e.attr({'x1_orig':e.attr('x1')}); - if (e.attr('x2_orig') === undefined) e.attr({'x2_orig':e.attr('x2')}); - var x1 = parseInt(e.attr('x1_orig')||e.attr('x_orig')); - var x2 = parseInt(e.attr('x2_orig')||e.attr('x_orig')); - x1 = x1*d.scaleX+d.offsetX+o; - x2 = x2*d.scaleX+d.offsetX+o; - e.attr({'x1':x1,'x2':x2}); - } else if (e.attr('x')) { // point - if (e.attr('x_orig') === undefined) e.attr({'x_orig':e.attr('x')}); - var x = parseInt(e.attr('x1_orig')||e.attr('x_orig')); - x = x*d.scaleX+d.offsetX+o; - e.attr({'x':x}); - } - } - - var distance = _currentDistance + offset; - subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); - subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,offset);}); - subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,offset);}); - - var distance = _currentDistance-_data.graphArea.width*scale + offset; - var subobject = _baseobject.find("[id=baseforDDD-previous]"); - subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); - subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,-_data.graphArea.width*scale+offset);}); - subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,-_data.graphArea.width*scale+offset);}); - - var distance = _currentDistance+_data.graphArea.width*scale + offset; - var subobject = _baseobject.find("[id=baseforDDD-next]"); - subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); - subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,_data.graphArea.width*scale+offset);}); - subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,_data.graphArea.width*scale+offset);}); - - // check if other charts are in the same scrollgroup and shift them as well - if (!noprop) { - var theDoc = (_data.popup)?_baseobject:$(document); - theDoc.find("[class^=basesvg]").each(function() { - if ($(this).parent().is(':visible')) { - var data = $(this).parent().data(); - if ((data.scrollgroup == _data.scrollgroup) && _data.scrollgroup!==undefined && _data.instance!=data.instance && data.baseDone) { - widget_chart.shiftXContent($(this),_currentDistance,_currentScale,_currentScaleDelta,data,true); - } - } - }); - } - }, - detectSwipe: function(target,remove) { // helper function to handle swipe and pinch events - var maxTime = 1000, // allow movement if < 1000 ms (1 sec) - startX = 0, - startXMove = 0, - startScaleX = 1, - startTime = 0, - lastTap = 0, - scaling = false, - pinchDist = 0, - timeout, - startTouches = [], - startLeftOffset = [], - touch = "ontouchend" in document, - startEvent = (touch) ? 'touchstart' : 'mousedown', - moveEvent = (touch) ? 'touchmove' : 'mousemove', - pinchEvent = (touch) ? 'gestureend' : '', - endEvent = (touch) ? 'touchend' : 'mouseup'; - var e = false; - - target.on(startEvent, function(_e){ - if (!_e.originalEvent.touches) { // no 2 finger gestures are suppoprted, simulate it. - if (!e) e = {timeStamp:_e.timeStamp, delegateTarget:_e.delegateTarget, preventDefault:_e.preventDefault, ctrlKey:_e.ctrlKey, stopPropagation:_e.stopPropagation, originalEvent:{touches:[]}}; - e.ctrlKey = _e.ctrlKey; - e.originalEvent.touches[0] = { - pageX:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX, - pageY:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY}; - e.originalEvent.touches[1] = { - pageX:(_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX)-100, - pageY:(_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY)-100}; - e.timeStamp = _e.timeStamp; - } else { - e = _e; - } - //console.log("Start Event",e); - // prevent image drag (Firefox) - var baseobject = $(e.delegateTarget).parents("[class^=basesvg]").parent(); - var data = baseobject.data(); - if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. - - _e.preventDefault(); - _e.stopPropagation(); - - startTime = e.timeStamp; - startX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; - startXMove = data.startXMove?data.startXMove:0; // keep actual shift in x direction in mind - data.movingX = true; - startScaleX = data.scaleX; - - if (e.originalEvent.touches && e.originalEvent.touches.length && e.originalEvent.touches.length === 2) { - if ((!_e.originalEvent.touches && e.ctrlKey) || _e.originalEvent.touches) { - scaling = true; - data.offsetX = data.offsetX + data.scaleDeltaX; - data.scaleDeltaX = 0; - } - startTouches[0] = e.originalEvent.touches[0].pageX; - startTouches[1] = e.originalEvent.touches[1].pageX; - } - baseobject.data(data); - }) - .on(endEvent, function(_e){ - //console.log("End Event",e); - var baseobject = $(_e.delegateTarget).parents("[class^=basesvg]").parent(); - var data = baseobject.data(); - if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. - if (data.crosshair) return; - - _e.preventDefault(); - _e.stopPropagation(); - - var currentTime = new Date().getTime(); - var tapLength = currentTime - lastTap; - - clearTimeout(timeout); - if (tapLength < 500 && tapLength > 0){ // double click/tap, reset interactive scaling/shifting - - scaling = false; - data.movingX = false; - startX = 0; - widget_chart.shiftXContent(baseobject,0,1,0,data); - - } else { - - //Single Tap/Click - - timeout = setTimeout(function(){ - clearTimeout(timeout); - }, 500); - } - - lastTap = currentTime; - - scaling = false; - startX = 0; - startTime = 0; - data.movingX = false; - baseobject.data(data); - - }) - .on(moveEvent, function(_e){ - if (!_e.originalEvent.touches) { // no 2 finger gestures are suppoprted, simulate it. - if (!e) e = {timeStamp:_e.timeStamp, delegateTarget:_e.delegateTarget, preventDefault:_e.preventDefault, ctrlKey:_e.ctrlKey, stopPropagation:_e.stopPropagation, originalEvent:{touches:[]}}; - e.ctrlKey = _e.ctrlKey; - e.originalEvent.touches[0] = { - pageX:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX, - pageY:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY}; - } else { - e = _e; - } - - //console.log("Move Event",e); - var baseobject = $(e.delegateTarget).parents("[class^=basesvg]").parent(); - var data = baseobject.data(); - if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. - - _e.preventDefault(); - _e.stopPropagation(); - - var started = data.movingX; - if (!started) return; - var maxDistance = data.graphArea.width - (data.prefetch?1:50); // start reloading new data when distance to chart border is lower than 50 pixels - - if (data.crosshair) return; - - var getScaleDelta = function(current,start,scale,left) { - var startLeftOffset = [start[0]-left,start[1]-left]; - var currentLefOffset = [current[0]-left,current[1]-left]; - return ((currentLefOffset[0] - startLeftOffset[0]*scale)+(currentLefOffset[1] - startLeftOffset[1]*scale))/2; - } - - if (scaling) { - var newTouches = [e.originalEvent.touches[0].pageX, e.originalEvent.touches[1].pageX]; - var scaleCurrent = (newTouches[0] - newTouches[1])/(startTouches[0] - startTouches[1]); - var scaleX = scaleCurrent*startScaleX; - - var delta = getScaleDelta(newTouches,startTouches,scaleCurrent,data.graphArea.left); - - if (!data.DDD.has3D) { // no transform feature, so we can not use the live movement of the graphs. - if (scaleX < 0.9) { - widget_chart.scaleTime(e,baseobject,2); - data.movingX = false; - scaling = false; - startX = 0; - scaleX = 1; - } else if (scaleX > 1.1) { - widget_chart.scaleTime(e,baseobject,0.5); - data.movingX = false; - scaling = false; - startX = 0; - scaleX = 1; - } - return; - } - - if (scaleX < 0.5) { - scaling = false; - data.movingX = false; - startX = 0; - scaleX = 1; - startTime = 0; - var offsetX = data.offsetX; - widget_chart.scaleTime(e, baseobject, 2, true, true, function() { - widget_chart.shift(e, baseobject, 0, true, false, function(){ - data = baseobject.data(); - widget_chart.shiftXContent(baseobject,(offsetX),scaleX,0,data); - }); - }); - } else if (scaleX > 2) { - scaling = false; - data.movingX = false; - startX = 0; - scaleX = 1; - startTime = 0; - var offsetX = data.offsetX; - widget_chart.scaleTime(e, baseobject, 0.5, true, true, function() { - widget_chart.shift(e, baseobject, 0, true, false, function(){ - data = baseobject.data(); - widget_chart.shiftXContent(baseobject,(offsetX),scaleX,0,data); - }); - }); - } else { - widget_chart.shiftXContent(baseobject,data.offsetX,scaleX,delta,data); - } - } else { - var currentX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX, - currentDistance = (startX === 0) ? 0 : (currentX - startX + startXMove), - // allow if movement < 1 sec - currentTime = e.timeStamp; - - if (!data.DDD.has3D) { // no transform feature, so we can not use the live movement of the graphs. - if (Math.abs(currentDistance) > 100) { - if (currentX < startX) { - widget_chart.shift(e, baseobject, -1, true); - } - - if (currentX > startX) { - widget_chart.shift(e, baseobject, 1, true); - } - data.movingX = false; - startTime = 0; - startX = 0; - } - return; - } - - widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); - - // currentDistance = (startX === 0) ? 0 : Math.abs(currentX - startX), - // allow if movement < 1 sec - currentTime = e.timeStamp; - if (Math.abs(currentDistance) > maxDistance) { - if (currentX < startX) { - // swipe left code here - widget_chart.shift(e, baseobject, -1, true, false, function() { - currentDistance = 0; - widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); - }); - } - if (currentX > startX) { - // swipe right code here - widget_chart.shift(e, baseobject, 1, true, false, function() { - currentDistance = 0; - widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); - }); - } - data.movingX = false; - startTime = 0; - startX = 0; - } - } - }); - }, checkEvent: function(event) { // helper function to do some special treatments/preparations for events event.preventDefault(); - var data = $(event.delegateTarget).parents("[class^=basesvg]").parent().data(); - if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. + var data = $(event.delegateTarget).parents("[class^=basesvg]").parent().data; if (!data.last_mousemove_pos) data.last_mousemove_pos = {'x':-1,'y':-1}; var x = event.pageX; @@ -2303,31 +1730,13 @@ var widget_chart = { theDoc.find("[class^=basesvg]").each(function() { if ($(this).parent().is(':visible')) { var data = $(this).parent().data(); - if ((data.cursorgroup == dataE.cursorgroup) && dataE.cursorgroup!==undefined && dataE.instance!=data.instance && data.baseDone) { + if ((data.cursorgroup == dataE.cursorgroup) && dataE.cursorgroup!==undefined && dataE.instance!=data.instance) { var dShift = data.days_start-dataE.days_start; var sc = data.days_start-data.days_end; var scW = data.graphArea.width/dataE.graphArea.width; var e = $.Event(event.type); - if (event.originalEvent && event.originalEvent.touches) { - e.originalEvent = JSON.parse(JSON.stringify(event.originalEvent)); - if (event.originalEvent.touches && event.originalEvent.touches[0]) { - var x = data.graphArea.left + ((event.originalEvent.touches[0].pageX-dataE.offsetX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW+data.offsetX+data.scaleDeltaX; - var point = {x: x, y: event.originalEvent.touches[0].pageY }; - - e.originalEvent.touches = [{ - target: event.originalEvent.target, - identifier: event.originalEvent.identifier, - pageX: x, - pageY: event.originalEvent.touches[0].pageY, - screenX: x, - screenY: event.originalEvent.touches[0].pageY, - clientX: x, - clientY: event.originalEvent.touches[0].pageY - }] - } - } else { - e.pageX = data.graphArea.left + ((event.pageX-dataE.offsetX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW+data.offsetX+data.scaleDeltaX; - } + if (event.originalEvent) e.originalEvent = event.originalEvent; + e.pageX = data.graphArea.left + ((event.pageX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW; e.delegateTarget = $(this).find("rect.chart-background, [id*='graph-']"); widget_chart.doEvent(e); } @@ -2345,7 +1754,6 @@ var widget_chart = { var values = []; var ind; var prefix; - var p_n_offset; crht.each(function(index) {crh_text[index] = $(this);}); switch (event.type) { // split into different activities for different events @@ -2361,8 +1769,7 @@ var widget_chart = { if (data.crosshair) { //console.log("Mouseenter Event",$(event.delegateTarget).parents("[class^=basesvg]").parent().data'crs_inactive')); if (crosshair && !data.crs_inactive && data.pointsarrayCursor) { - var x = ((evt.pageX - data.chartArea.left)); -// var x = ((evt.pageX - data.chartArea.left - data.offsetX) - data.graphArea.width*(1-data.scaleX))/data.scaleX) - data.graphArea.width*(1-data.scaleX))/data.scaleX; + var x = (evt.pageX - data.chartArea.left); var y = (evt.pageY - data.chartArea.top); var noticks = ( data.width <=100 ) ? true : target.parent().hasClass('noticks'); if (data.logProxy) { @@ -2377,47 +1784,21 @@ var widget_chart = { //crosshair.find('line.crosshair').attr({'x1':x, 'y1':data.topOffset, 'x2':x, 'y2':data.chartArea.height-(noticks?0:data.bottomOffset)}); widget_chart.movetoLine(event.type,crosshair.find('line.crosshair'),x,data.topOffset,x,data.chartArea.height-(noticks?0:data.bottomOffset),100,function(x1f,y1f,x2f,y2f){}); values=[]; - ind = parseInt((x-data.getOffsetX())/data.scaleX+0.5); - if (ind < parseInt(data.graphArea.left-data.chartArea.left+0.5)) { - if (data.pointsarrayCursor_prev && data.pointsarrayCursor_prev.length) { - ind = parseInt(Math.max(ind+data.graphArea.width,0)+0.5); - values = data.pointsarrayCursor_prev[ind]; - p_n_offset = -data.graphArea.width*data.scaleX+data.getOffsetX(); - } else { - values = data.pointsarrayCursor[0]; - p_n_offset = data.getOffsetX(); - } - } else if (ind >= data.pointsarrayCursor.length) { - if (data.pointsarrayCursor_prev && data.pointsarrayCursor_prev.length) { - ind = parseInt(Math.min(ind-data.graphArea.width,data.pointsarrayCursor_next.length)+0.5); - values = data.pointsarrayCursor_next[ind]; - p_n_offset = data.graphArea.width*data.scaleX+data.getOffsetX(); - } else { - values = data.pointsarrayCursor[data.pointsarrayCursor.length-1]; - p_n_offset = data.getOffsetX(); - } - } else { - values = data.pointsarrayCursor[ind]; - p_n_offset = data.getOffsetX(); - } - //ind = ((parseInt(x+0.5)<=0)?0:((parseInt(x+0.5)>=data.pointsarrayCursor.length)?data.pointsarrayCursor.length-1:(parseInt(x+0.5)))); - //values = data.pointsarrayCursor[ind]; + ind = ((parseInt(x+0.5)<=0)?0:((parseInt(x+0.5)>=data.pointsarrayCursor.length)?data.pointsarrayCursor.length-1:(parseInt(x+0.5)))); + values = data.pointsarrayCursor[ind]; } var lastV = data.lastV; var uxis; var i,il; var legendY; - var minclip = data.graphArea.top - data.chartArea.top; - var maxclip = data.graphArea.height + minclip; if (!lastV) lastV = values; - if (!values) values = []; for (i=0,il=values.length; i=minclip && legendY<=maxclip) { + if (data.graphsshown[i]) { crh_text[i].show(); crh_text[i].find('tspan.crosshairValue').html(valtxt); } else { crh_text[i].hide(); } - widget_chart.moveto(crh_text[i],values[i][0]*data.scaleX+p_n_offset,legendY,50,function(xf,yf){}); + widget_chart.moveto(crh_text[i],values[i][0],legendY,50,function(xf,yf){}); /* var rw = widget_chart.getTextSizePixels(target,prefix + valtxt,'text crosshair').width; var rh = widget_chart.getTextSizePixels(target,prefix + valtxt,'text crosshair').height; if (!crh_text[i].parent().find('rect').length) { @@ -2454,7 +1835,7 @@ var widget_chart = { if (!data.logProxy) { // draw time value below x axis var itime=crh_text.length-1; legendY = data.graphHeight/100*target.height()+data.topOffset+widget_chart.getTextSizePixels(crh_text[itime].parents("[class^=basesvg]"),'O','crosshair').height; - var xminutes = ((x-data.getOffsetX())/data.scaleX-data.getGraphLeft())*100/data.basewidth*data.xrange/data.graphWidth; + var xminutes = (x-data.getGraphLeft())*100/data.basewidth*data.xrange/data.graphWidth; var tstart = ftui.dateFromString(data.mindate); var tx = new Date(tstart); var textX2Value, tarr; @@ -2472,8 +1853,7 @@ var widget_chart = { var rw = widget_chart.getTextSizePixels(target,textX2Value,'text crosshair').width; var rh = widget_chart.getTextSizePixels(target,textX2Value,'text crosshair').height; if (!crh_text[itime].parent().find('rect').length) { - crh_text[itime].parent().prepend(widget_chart.createElem('rect').attr({'class':'crosshair','x':x-rw/2,'y':legendY-rh/2,'width':rw+'px','height':rh+'px','style':'z-index:10000; fill:black;'})); - crh_text[itime].parent().find('rect.crosshair').parent().css('clip-path','none'); + crh_text[itime].parent().prepend(widget_chart.createElem('rect').attr({'class':'crosshair','x':x-rw/2,'y':legendY-rh/2,'width':rw+'px','height':rh+'px','style':'z-index:10000; fill:black'})); crh_text[itime].attr({'text-anchor':'middle'}); } crh_text[itime].parent().find('rect').attr({'x':x-rw/2, 'y':legendY-rh/2}); @@ -2530,21 +1910,19 @@ var widget_chart = { calcDiffMonth: function(ds,de,offset) { var width = Math.abs(ds-de); var now = new Date(); - var tstart = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); // get current time rounded to minutes - var tend = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); // get current time rounded to minutes - tstart.setTime(tstart.getTime() - (Math.max(ds,de)*24*60*60*1000)); // set tstart to maximum of ds/de less than current time - tend.setTime(tend.getTime() - (Math.min(ds,de)*24*60*60*1000)); // set tstart to minimum of ds/de less than current time + var tstart = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); + var tend = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); + tstart.setTime(tstart.getTime() - (Math.max(ds,de)*24*60*60*1000)); + tend.setTime(tend.getTime() - (Math.min(ds,de)*24*60*60*1000)); var ret = []; - if (width >= tstart.myGetDaysInMonth()) { // difference is bigger than current month care for correct treatment - var mdiff = tend.getMonth()-tstart.getMonth()+(tend.getFullYear()-tstart.getFullYear())*12; // get number of months between dates - var md = parseInt(mdiff*offset); - var dds = (mdiff*offset-md)*tstart.myGetDaysInMonth(); - var dde = (mdiff*offset-md)*tend.myGetDaysInMonth(); - var dateS = (tstart.getDate()==tstart.myGetDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tstart.getDate(); - var dateE = (tend.getDate()==tend.myGetDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tend.getDate(); - ret[0] = ds + widget_chart.dateDiff(new Date(tstart.getFullYear(),tstart.getMonth()-md,dateS-dds,tstart.getHours(),tstart.getMinutes(),0,0),tstart,'d'); - ret[1] = de + widget_chart.dateDiff(new Date(tend.getFullYear(),tend.getMonth()-md,dateE-dde,tend.getHours(),tend.getMinutes(),0,0),tend,'d'); + if (width >= tstart.getDaysInMonth()) { + var mdiff = tend.getMonth()-tstart.getMonth()+(tend.getFullYear()-tstart.getFullYear())*12; + var dateS = (tstart.getDate()==tstart.getDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-mdiff*offset,1,0,0,0,0).getDaysInMonth():tstart.getDate(); + var dateE = (tend.getDate()==tend.getDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-mdiff*offset,1,0,0,0,0).getDaysInMonth():tend.getDate(); + + ret[0] = ds + widget_chart.dateDiff(new Date(tstart.getFullYear(),tstart.getMonth()-mdiff*offset,dateS,tstart.getHours(),tstart.getMinutes(),0,0),tstart,'d'); + ret[1] = de + widget_chart.dateDiff(new Date(tend.getFullYear(),tend.getMonth()-mdiff*offset,dateE,tend.getHours(),tend.getMinutes(),0,0),tend,'d'); } else { ret[0] = ds + offset*width; ret[1] = de + offset*width; @@ -2571,22 +1949,17 @@ var widget_chart = { data.days_end = dRet[1]; break; default: - width = (data.days_start-data.days_end); + width = data.days_start-data.days_end; data.days_start = data.days_start+offset*(width); data.days_end = data.days_end+offset*(width); break; } }, - shift: function(evt,elem,offset,noanimation,norefresh,callback){ // calculate new start and end dates when user wants to shift graph + shift: function(evt,elem,offset){ // calculate new start and end dates when user wants to shift graph var dataE = elem.data(); - if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. dataE.shift += offset; - //widget_chart.doCorrectShift(dataE, offset); - if (!norefresh) { - widget_chart.refresh(elem,noanimation?'start reset':'shift',-offset,callback); - } else { - if (callback) callback(); - } + widget_chart.doCorrectShift(dataE, offset); + widget_chart.refresh(elem,'shift',-offset); // check if other charts are in the same scrollgroup and shift them as well var theDoc = (dataE.popup)?elem:$(document); @@ -2594,18 +1967,13 @@ var widget_chart = { var data = $(this).parent().data(); if ((data.scrollgroup == dataE.scrollgroup) && dataE.scrollgroup!==undefined && dataE.instance!=data.instance) { data.shift += offset; - //widget_chart.doCorrectShift(data, offset); - if (!norefresh) { - widget_chart.refresh($(this).parent(),noanimation?'start reset':'shift',-offset,callback); - } else { - if (callback) callback(); - } + widget_chart.doCorrectShift(data, offset); + widget_chart.refresh($(this).parent(),'shift',-offset); } }); }, rotate: function(evt,elem,rotx,roty){ // calculate new rotation values when 3D modus is activated var dataE = elem.data(); - if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. if (dataE.ddd === undefined) { return; @@ -2633,7 +2001,7 @@ var widget_chart = { doCorrectScale: function(data,scale) { // helper function for correction of scale due to given classifier ('y','m') var classifier = data.xclassifier; var width; - if (classifier == 'y' && (data.days_start-data.days_end)<365*2) classifier = 'm'; // if we will have less than two years difference use rounding to months instead of rounding to years + if (classifier == 'y' && (data.days_start-data.days_end)<365*2) classifier = 'm'; // if we will have less than one year difference use rounding to months instead of rounding to years switch (classifier) { case 'y': // correction needed for leap years width = widget_chart.correctLeapYear(data.days_start,data.days_end,'down'); // remove leap year days for old period @@ -2643,7 +2011,7 @@ var widget_chart = { break; case 'm': // correction needed due to different number of days per month width = data.days_start-data.days_end; - if (width>31 || scale > 1) { // new difference is surely more than a month => use corrected value + if (width>31 || scale > 1) { // new difference is more than a month => use calculated value var dRet = widget_chart.calcDiffMonth(data.days_start,data.days_end,scale-1); data.days_start = dRet[0]; } else { // do calculation without month correction @@ -2663,19 +2031,19 @@ var widget_chart = { if (!$.isArray(dataE.timeranges)) return; // there is no definition of timeranges, do nothing var selBtn = $(evt.delegateTarget); - //widget_chart.doLog("widget_chart.selectTime","test: "+window.pageXOffset+", "+window.pageYOffset); + widget_chart.doLog("widget_chart.selectTime","test: "+window.pageXOffset+", "+window.pageYOffset); //elem.find("[id='selectTimePulldown_"+dataE.instance+"']").remove(); // remove old pulldown if it is still there. var pulldownMenu = elem.find("[id='selectTimePulldown_"+dataE.instance+"']"); if (!pulldownMenu.length || pulldownMenu.length == 0) { pulldownMenu = $(document.createElement('div')).attr({ - 'style': 'width: auto; display:none; position: absolute; z-index: 10000; left:'+ - (elem.find('.buttons.timeranges').offset().left-elem.offset().left)+'px; top:'+ - (elem.find('.buttons.timeranges').offset().top-elem.offset().top+elem.find('.buttons.timeranges')[0].getBoundingClientRect().height)+'px;', + 'style': 'width: auto; display:none; position: absolute; left:'+ + (evt.pageX-elem.parent().offset().left)+'px; top:'+ + (evt.pageY-elem.parent().offset().top)+'px;', 'class': 'pulldownmenu', 'id': 'selectTimePulldown_'+dataE.instance }); $.each( dataE.timeranges, function( ind, value ) { - var pdEntry = $(document.createElement('div')).attr({'class':"pdentry",'style':'z-index: 10000;'}); + var pdEntry = $(document.createElement('div')).attr({'class':"pdentry"}); pdEntry.text(value[0]); pulldownMenu.append(pdEntry); pdEntry.data('timerrange',value); @@ -2688,8 +2056,7 @@ var widget_chart = { elem.data('daysago_end',$(e.delegateTarget).data('timerrange')[2]); elem.data('scale', 1); // set scale value to initial value elem.data('shift', 0); // set shift value to initial value - elem.data('iZoom',-1); // reset zoom array used when clicking at x-axis labels - widget_chart.refresh(elem,'start reset',0); + widget_chart.refresh(elem,'start',0); // check if other charts are in the same scrollgroup and shift them as well var theDoc = (dataE.popup)?elem:$(document); @@ -2701,8 +2068,7 @@ var widget_chart = { elm.data('daysago_end',$(e.delegateTarget).data('timerrange')[2]); elm.data('scale', 1); // set scale value to initial value elm.data('shift', 0); // set shift value to initial value - elm.data('iZoom',-1); // reset zoom array used when clicking at x-axis labels - widget_chart.refresh($(this).parent(),'start reset',0); + widget_chart.refresh($(this).parent(),'start',0); } }); } @@ -2713,33 +2079,25 @@ var widget_chart = { elem.append(pulldownMenu); } - pulldownMenu.slideDown(400,function() {$(document).on('click.pdClicks', function(e) { + pulldownMenu.slideDown(400,function() {$(document).bind('click.pdClicks', function(e) { pulldownMenu.hide(); - $(document).off('click.pdClicks'); + $(document).unbind('click.pdClicks'); })}); }, - scaleTime: function(evt,elem,scale,noanimation,norefresh,callback){ // calculate new start and end dates when user wants to scale graph + scaleTime: function(evt,elem,scale){ // calculate new start and end dates when user wants to scale graph var dataE = elem.data(); - if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. dataE.scale *= scale; - //widget_chart.doCorrectScale(dataE,scale); - if (!norefresh) { - widget_chart.refresh(elem,noanimation?'start reset':'scale',0,callback); - } else { - if (callback) callback(); - } + widget_chart.doCorrectScale(dataE,scale); + widget_chart.refresh(elem,'scale',0); + // check if other charts are in the same scrollgroup and scale them as well var theDoc = (dataE.popup)?elem:$(document); theDoc.find("[class^=basesvg]").each(function() { var data = $(this).parent().data(); if ((data.scrollgroup == dataE.scrollgroup) && dataE.scrollgroup!==undefined && dataE.instance!=data.instance) { data.scale *= scale; - //widget_chart.doCorrectScale(data,scale); - if (!norefresh) { - widget_chart.refresh($(this).parent(),noanimation?'start reset':'scale',0,callback); - } else { - if (callback) callback(); - } + widget_chart.doCorrectScale(data,scale); + widget_chart.refresh($(this).parent(),'scale',0); } }); }, @@ -2841,8 +2199,6 @@ var widget_chart = { currval += (currval maxwidth) {maxwidth = wdth;} lwidths[i] = wdth+2.5; sumwidth += lwidths[i]; @@ -2980,10 +2329,10 @@ var widget_chart = { legend_container.prepend(widget_chart.createElem('rect').attr({'class':'lback'})); legend_container.find('rect.lback') // add drag functionality for legend container .draggable() - .on('mouseover', function(event) { + .bind('mouseover', function(event) { event.target.setAttribute('style','cursor:move'); }) - .on('mousedown touchstart', function(event, ui){ + .bind('mousedown touchstart', function(event, ui){ var evt; // keep initial mouse position relative to draggable object. if (event.type == 'touchstart') { @@ -2996,7 +2345,7 @@ var widget_chart = { xS = parseFloat($(evt.target).attr('x')) - (evt.pageX - target.offset().left); yS = parseFloat($(evt.target).attr('y')) - (evt.pageY - target.offset().top); }) - .on('drag touchmove', function(event, ui) { + .bind('drag touchmove', function(event, ui) { var evt; if (event.type == 'touchmove') { if (!event.originalEvent) return; @@ -3024,7 +2373,7 @@ var widget_chart = { for (var k=0; k now.getTime())) { - data.filltime_end_save = data.filltime_end; - data.filltime_end = false; - } else { - data.filltime_end = data.filltime_end_save; - } - - data.baseDone = false; // chart has to be redrawn, set flag to control right order between 'acutal', 'previous' and 'next' - data.openDrawings = data.prefetch?3:1; // number of drawings to be done needed for checking when to activate event handling for scale and shift $(theObj).data(data); - promiseAct = widget_chart.retrieveData(elem,type,swoffset,data_old,'actual',callback,true); - if (data.prefetch) { - promisePrev = widget_chart.retrieveData(elem,type,swoffset,data_old,'previous',callback,true); - promiseNext = widget_chart.retrieveData(elem,type,swoffset,data_old,'next',callback,true); - } - } else { - data.baseDone = false; // chart has to be redrawn, set flag to control right order between 'acutal', 'previous' and 'next' - data.openDrawings = data.prefetch?(type=='shift'?2:3):1; // number of drawings to be done needed for checking when to activate event handling for scale and shift - $(theObj).data(data); - widget_chart.drawChart(elem,type,swoffset,data_old,callback); - //if (data.prefetch && !(type=='shift' && swoffset==-1)) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous'); - //if (data.prefetch && !(type=='shift' && swoffset==1)) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next'); - } - if ((data.filltime_start || data.filltime_end) && data.prefetch) { // we need to correct the "artificial" data points and thus need to wait for all d - $.when(promiseAct,promiseNext,promisePrev).done(function() { - widget_chart.drawChart(elem,type,swoffset,data_old,callback); - if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous'); - if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next'); - }); + widget_chart.retrieveData(elem,type,swoffset,data_old,'actual'); + if (data.prefetch) widget_chart.retrieveData(elem,type,swoffset,data_old,'previous'); + if (data.prefetch) widget_chart.retrieveData(elem,type,swoffset,data_old,'next'); } else { - $.when(promiseAct,promisePrev).done(function() {if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous');}); - $.when(promiseAct,promiseNext).done(function() {if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next');}); + widget_chart.drawChart(elem,type,swoffset,data_old); } }, - retrieveData: function(elem,type,swoffset,data_old,cachetype,callback,draw) { + retrieveData: function(elem,type,swoffset,data_old,cachetype) { var theObj; - if (elem) theObj=elem; else theObj=this; + if (elem) theObj=elem; else theObj=this; var data = $(theObj).data(); + //check the input arrays to derive the one with biggest length data.nGraphs = widget_chart.getnGraphs(data); - var deferred = new $.Deferred(); - $(theObj).data('runningRefresh',true); for (var k=0; k 0) { // add additional data points at beginning and end of chart area - var fillstart = (data.filltime_start && (cachetype == 'actual' || cachetype == 'previous')) || (data.filltime_end && cachetype == 'next'); - var fillend = (data.filltime_end && (cachetype == 'actual' || cachetype == 'next')) || (data.filltime_start && cachetype == 'previous'); - if (points[1][0] != 0 && fillstart) { - points[0] = points[1].clone(); - points[0][0] = 0; - } else { // first point is already at leftmost position, shift the array - points.shift(); - } - if (points[points.length-1][0] != ftui.diffMinutes(tstart,tend) && fillend) { - points[points.length] = points[points.length-1].clone(); - points[points.length-1][0] = ftui.diffMinutes(tstart,tend); - } - } - - if (ics > 0) $(theObj).data().nofilldown[slot] = true; // there is a columnspec given as array, do not fill down to x-axes but fill area between the 2 curves + if (ics > 0) data.nofilldown[slot] = true; // there is a columnspec given as array, do not fill down to x-axes but fill area between the 2 curves - $(theObj).data().columnspecsDone[cachetype][slot]++; + data.columnspecsDone[cachetype][slot]++; if (cachetype == 'previous') { - $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray_prev,$(theObj).data().pointsstr_prev,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); - if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx_prev++; // all columnspecs for this slot are processed, count up slot - if ($(theObj).data().kIndx_prev==$(theObj).data().nGraphs) { - $(theObj).data().previous_cache_completed = true; - deferred.resolve(); - } + data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray_prev,data.pointsstr_prev,points,points_str,ics,data.last_ics[cachetype][slot]); + if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx_prev++; // all columnspecs for this slot are processed, count up slot + $(theObj).data(data); + if (data.kIndx_prev==data.nGraphs) data.previous_cache_completed = true; } else if (cachetype == 'next') { - $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray_next,$(theObj).data().pointsstr_next,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); - if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx_next++; // all columnspecs for this slot are processed, count up slot - if ($(theObj).data().kIndx_next==$(theObj).data().nGraphs) { - $(theObj).data().next_cache_completed = true; - deferred.resolve(); - } + data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray_next,data.pointsstr_next,points,points_str,ics,data.last_ics[cachetype][slot]); + if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx_next++; // all columnspecs for this slot are processed, count up slot + $(theObj).data(data); + if (data.kIndx_next==data.nGraphs) data.next_cache_completed = true; } else { - $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray,$(theObj).data().pointsstr,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); - if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx++; // all columnspecs for this slot are processed, count up slot - if ($(theObj).data().kIndx==$(theObj).data().nGraphs) { // last slot to be retrieved start painting chart - if (!(($(theObj).data().filltime_start || $(theObj).data().filltime_end) && $(theObj).data().prefetch)) widget_chart.drawChart(theObj,type,swoffset,data_old,callback); - deferred.resolve(); + data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray,data.pointsstr,points,points_str,ics,data.last_ics[cachetype][slot]); + if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx++; // all columnspecs for this slot are processed, count up slot + $(theObj).data(data); + if (data.kIndx==data.nGraphs) { // last slot to be retrieved start painting chart + widget_chart.drawChart(elem,type,swoffset,data_old); } } //last point is repetition of column spec, dont add @@ -3434,81 +2710,12 @@ var widget_chart = { }); } } - return deferred.promise(); }, - interpolate: function(leftx,lefty,rightx,righty,x) { - var ret = 0; - if (leftx!=undefined && lefty!=undefined && rightx!=undefined && righty!=undefined && x!=undefined) { - if ((rightx-leftx) != 0) { - ret = lefty + (x-leftx)/(rightx-leftx)*(righty-lefty); - } else { - ret = (lefty+righty)/2; - } - } - return ret; - }, - correctPoints4Filltime: function(data,igraph,p0,cachetype) { - if ((data.filltime_start || data.filltime_end) && data.prefetch) { // if data points have been added at beginning and end, make them consistent with previous and next arrays if existing - if (cachetype == 'previous' && data.filltime_start) { - var p1 = data.pointsarray[igraph]; - if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { - p0[p0.length-1][1] = widget_chart.interpolate( - parseFloat(p0[p0.length-2][0]), - parseFloat(p0[p0.length-2][1]), - parseFloat(p1[1][0])+parseFloat(p0[p0.length-1][0]), // in fillmode this is the distance to the leftmost point - parseFloat(p1[1][1]), - parseFloat(p0[p0.length-1][0])); // in filltime mode this is the rightmost point - } - } - if (cachetype == 'next' && data.filltime_end) { - var p1 = data.pointsarray[igraph]; - if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { - p0[0][1] = widget_chart.interpolate( - parseFloat(p0[1][0]), - parseFloat(p0[1][1]), - parseFloat(p1[p1.length-2][0])-parseFloat(p1[p1.length-1][0]), // in fillmode this is the negative distance to the rightmost point - parseFloat(p1[p1.length-2][1]), - parseFloat(p0[0][0])); // in filltime mode this is the leftmost point - } - } - if (cachetype == undefined) { - if (data.filltime_start) { - var p1 = data.pointsarray_prev[igraph]; - if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { - p0[0][1] = widget_chart.interpolate( - parseFloat(p0[1][0]), - parseFloat(p0[1][1]), - parseFloat(p1[p1.length-2][0])-parseFloat(p1[p1.length-1][0]), // in fillmode this is the negative distance to the rightmost point - parseFloat(p1[p1.length-2][1]), - parseFloat(p0[0][0])); // in filltime mode this is the leftmost point - } - } - if (data.filltime_end) { - var p1 = data.pointsarray_next[igraph]; - if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { - p0[p0.length-1][1] = widget_chart.interpolate( - parseFloat(p0[p0.length-2][0]), - parseFloat(p0[p0.length-2][1]), - parseFloat(p1[1][0])+parseFloat(p0[p0.length-1][0]), // in fillmode this is the distance to the leftmost point - parseFloat(p1[1][1]), - parseFloat(p0[p0.length-1][0])); // in filltime mode this is the rightmost point - } - } - } - } - }, - drawChart: function (elem,intype,swoffset,data_old,callback,cachetype) { // main function for generation of all HTML code and dynamics for graph called whenever thigs change (e.g. data update, shift, scale, ...) + drawChart: function (elem,type,swoffset,data_old) { // main function for generation of all HTML code and dynamics for graph called whenever thigs change (e.g. data update, shift, scale, ...) var theObj; if (elem) theObj=elem; else theObj=this; - $(theObj).data('drawing',true); var data = $(theObj).data(); - //console.log(cachetype==undefined?'actual':cachetype); - var data_save = jQuery.extend(true,{},$(theObj).data()); // keep original data in order to reset at end of 'previous' and 'next' calls - //if (cachetype && !data.baseDone) return; - var type = intype.split(' ')[0]; // derive the first word of type (second word sets reset flag) - var doReset = intype.split(' ')[1]?(intype.split(' ')[1]=='reset'):false; // derive the first word of type (second word sets reset flag) if (type=="resize") data.legend_pos = undefined; - //console.log('start --> ',cachetype, data.baseDone, pointsarray,new Error().stack); var y_margin = []; if ($.isArray(data.y_margin)) y_margin=[parseInt(data.y_margin[0]),parseInt(data.y_margin[data.y_margin.length-1])]; else y_margin=[parseInt(data.y_margin),parseInt(data.y_margin)]; @@ -3526,20 +2733,7 @@ var widget_chart = { data.noticks = noticks; data.leftOffset = 0; - doReset = doReset || type=='shift' || type=='scale' || data.offsetX===undefined || data.scaleX===undefined || data.scaleDeltaX===undefined; - if (doReset) { - data.offsetX = 0; // offset for shifting arbitrarily due to mousemove and touchmove handling - data.scaleX = 1; // scale for scaling arbitrarily due to mousemove and touchmove handling - data.scaleDeltaX = 0; // scale for scaling arbitrarily due to mousemove and touchmove handling - } - - if (cachetype=='next') { - data.shift -= 1; - } else if (cachetype=='previous') { - data.shift += 1; - } widget_chart.initializeTime(data); - //console.log(cachetype+": ",data.days_start, data.days_end, data.shift, data.scale, new Error().stack); var DDD = {}; if (!data.DDD) data.DDD = DDD; @@ -3569,7 +2763,7 @@ var widget_chart = { return ret+DDD.Width(n); }; - data.getGraphLeft = function() {var ret = this.noticks?this.leftOffset:this.leftOffset+(this.unusedYAxesVisible?this.textWidth_prim.sum():this.textWidth_prim.max()); return ret;}; + data.getGraphLeft = function() {var ret = this.noticks?this.leftOffset:this.leftOffset+this.textWidth_prim.sum(); return ret;}; data.transform = function (value,type,transfunc) { // do any kind of functional transformation of scaled y values in the original y data space var valData = (this.isPrimary(type))?(value+this.shiftY)/this.scaleY:(value+this.shiftY_sec)/this.scaleY_sec; @@ -3605,7 +2799,7 @@ var widget_chart = { } else { value = this[par+extension]; } - return $.isArray(value)?value[0]:value; + return value; }; data.getYAxisDisplayPrio = function(uxs,aindex) { @@ -3626,18 +2820,12 @@ var widget_chart = { return res; }; - data.getOffsetX = function(inv) {return this.offsetX + this.scaleDeltaX;}; - - data.popup = ($(theObj).parent().data().id && $(theObj).parent().data().id.match(/popup_.*/))?true:false; + if ($(theObj).parent().parent().data()) data.popup = ($(theObj).parent().parent().data().type == 'popup'); else data.popup = false; var instance = data.instance; var svg_old = $(theObj).find('svg.basesvg'+instance); // get previous graphics document (SVG, only skeleton at initial call) - - // unregister events for swipe - //if (!data.logProxy) widget_chart.detectSwipe(svg_old.find("rect.chart-background, [id*='graph-']"),true); - - if (!svg_old.parent().is(':visible') || svg_old.width()<=0) {if (!cachetype) $(theObj).data('baseDone',true); return}; // chart div is not visible nothing to do + if (!svg_old.parent().is(':visible') || svg_old.width()<=0) return; // chart div is not visible nothing to do if (svg_old.height() <= 0) { data.getDefaultSize($(theObj)); @@ -3649,30 +2837,27 @@ var widget_chart = { } var classesContainer = svg_old.find('#classesContainer'); + data.yLimits = []; - if (!cachetype) { - data.yLimits = []; - - for (k=0; k'+ ' '+ ' '+ - ' '+ - ' '+ - ' '+ ' '+ ' '+ ' '+ @@ -4243,64 +3278,6 @@ var widget_chart = { ''+ ''+ ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ' '+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - 'Produces a 3D lighting effect.'+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ ''+ ''+ ''+ @@ -4330,7 +3307,7 @@ var widget_chart = { clip.left = data.getGraphLeft(); var zBack = (data.DDD.Setting[0] && data.DDD.Setting[0]<0)?data.DDD.BackplaneZ(data.DDD,data.nGraphs):0; var zFore = (data.DDD.Setting[0] && data.DDD.Setting[0]<0)?0:data.DDD.BackplaneZ(data.DDD,data.nGraphs); - clip.right = noticks?data.leftOffset+data.graphArea.width:data.leftOffset+(data.unusedYAxesVisible?data.textWidth_prim.sum():data.textWidth_prim.max())+data.graphArea.width/data.DDD.scaleX; + clip.right = noticks?data.leftOffset+data.graphArea.width:data.leftOffset+data.textWidth_prim.sum()+data.graphArea.width/data.DDD.scaleX; var p1 = widget_chart.getTransformedPoint(data,theObj,{x:0,y:data.graphHeight/100*data.baseheight,z:zBack}); var p2 = widget_chart.getTransformedPoint(data,theObj,{x:data.graphWidth/100*data.basewidth,y:data.graphHeight/100*data.baseheight,z:zBack}); clip.bottom = (Math.max(p1.y,p2.y)-data.DDD.shiftY)/data.DDD.scaleY; @@ -4342,11 +3319,7 @@ var widget_chart = { var svg_new = $( '' + (data.title?data.title_object:'') + '' + - '' + - ''+widget_chart.getClipPath(data,0,theObj,0)+widget_chart.getClipPath(data,0,theObj,0)+''+ - ''+widget_chart.getClipPath(data,0,theObj,3)+widget_chart.getClipPath(data,0,theObj,3)+''+ - ''+widget_chart.getClipPath(data,0,theObj,1)+widget_chart.getClipPath(data,0,theObj,1)+''+ - ''+widget_chart.getClipPath(data,0,theObj,2)+widget_chart.getClipPath(data,0,theObj,2)+''+ + '' + ''+ ''+ ''+ @@ -4354,8 +3327,13 @@ var widget_chart = { ''+ ''+ ''+ - '' + - ''+ + '' + + ''+ + ''+ + ''+ + ''+ + '' + + ''+ ''+ ''+ ''+ @@ -4378,7 +3356,7 @@ var widget_chart = { svg_new.find("rect.chart-background").attr(attrval); // test for functions on touch devices, currently not running yet - /*svg_new.find("rect.chart-background, [id*='graph-']").on("click", function(event) { + svg_new.find("rect.chart-background, [id*='graph-']").on("click", function(event) { }); svg_new.find("rect.chart-background, [id*='graph-']").on("swipeleft", function(event) { //$(event.delegateTarget).find("text.debug").text('Type: '+event.type+' X: '+event.pageX+' Y: '+event.pageY); @@ -4387,7 +3365,7 @@ var widget_chart = { svg_new.find("rect.chart-background, [id*='graph-']").on("swiperight", function(event) { //$(event.delegateTarget).find("text.debug").text('Type: '+event.type+' X: '+event.pageX+' Y: '+event.pageY); widget_chart.shift(event, $(event.delegateTarget),-1); - });*/ + }); var legend_container = widget_chart.drawLegend(data,theObj,style_array,fszC,classesContainer); @@ -4405,7 +3383,7 @@ var widget_chart = { // text element for show/hide of legend container var caption_text; if (!nobuttons) { - caption_text = widget_chart.createElem('text').attr({'class':'caption legendbutton'+(data.showlegend?' active':' inactive'),'x':(noticks)?(data.timeranges!=''?7.7*fszB:6.2*fszB):(data.timeranges!=''?7.7*fszB:6.2*fszB)+'px','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','style':'text-anchor:end'}); + caption_text = widget_chart.createElem('text').attr({'class':'caption'+(data.showlegend?' active':' inactive'),'x':'49%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','style':'text-anchor:end'}); caption_text.text("Legend"); legend_menu.append(caption_text); } @@ -4451,13 +3429,12 @@ var widget_chart = { for (var k=data.nGraphs-1; k>=0; k--) { // main loop for generation of page content (chart with graphs) uaxis = widget_chart.getArrayValue(uaxis_array,k,'primary'); AI = data.getAxisIndex(uaxis); + var unitsperpix = (data.yLimits[AI].primary.max-data.yLimits[AI].primary.min)/data.graphArea.height; // treat margin top and bottom if given if (data.isPrimary(uaxis) && !aiDone['primary'][AI]) { - var unitsperpix = (data.yLimits[AI].primary.max-data.yLimits[AI].primary.min)/data.graphArea.height; if (data.getAxisSetting('minvalue',uaxis)=="auto") data.yLimits[AI].primary.min -= y_margin[0]*unitsperpix; if (data.getAxisSetting('maxvalue',uaxis)=="auto") data.yLimits[AI].primary.max += y_margin[1]*unitsperpix; } else if (!aiDone['secondary'][AI]) { - var unitsperpix = (data.yLimits[AI].secondary.max-data.yLimits[AI].secondary.min)/data.graphArea.height; if (data.getAxisSetting('minvalue',uaxis)=="auto") data.yLimits[AI].secondary.min -= y_margin_sec[0]*unitsperpix; if (data.getAxisSetting('maxvalue',uaxis)=="auto") data.yLimits[AI].secondary.max += y_margin_sec[1]*unitsperpix; } @@ -4484,7 +3461,7 @@ var widget_chart = { widget_chart.scaleValues(pointsarray, k, data); var tstart = ftui.dateFromString(data.mindate); - style = widget_chart.getDynamicStyle(widget_chart.getArrayValue(style_array,k,'')); + style = widget_chart.getArrayValue(style_array,k,''); ptype = widget_chart.getArrayValue(ptype_array,k,'lines'); legend = widget_chart.getArrayValue(legend_array,k,'Graph '+k); @@ -4594,27 +3571,34 @@ var widget_chart = { points=pointsarray[k]; - //Setting the general attributes for different plot types - var fontFamily, fontWeight, symbol; - if (ptype.search('icons:')>=0) { - ptype = 'icons'; + if (ptype.search('icons:')>=0) { // copy data values to graphs which use ptype "icons:.." + var iv = ptype.split(':')[1]; + for (var i1=0, i1l=pointsarray[k].length; i1 pointsarray[k][i1][0]) { // found fitting reference value + pointsarray[k][i1][1] = pointsarray[iv][i2-1][1]; + found = true; + break; + } + } + if (!found) pointsarray[k][i1][1] = pointsarray[iv][i1][1]; // no fitting time value found, use last value of reference array instead + } + ptype = 'icons'; } else if (ptype.search(':')>=0) { ptype = ptype.split(':')[0]; } - + + //Setting the general attributes for different plot types + var fontFamily, symbol; if (ptype.indexOf('fa-')>=0 || ptype.indexOf('fs-')>=0 || ptype.indexOf('oa-')>=0) { //there seem to be font awesome symbols defined symbol = widget_chart.fontNameToUnicode(ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))); - fontFamily = (ptype.indexOf('fa-')>=0)?(ftui.version>'2.7.1'?'"Font Awesome 5 Free"':'FontAwesome'):(ptype.indexOf('fs-')>=0)?'fhemSVG':'openautomation'; - fontWeight = (ptype.indexOf('fa-')>=0)?(ftui.version>'2.7.1'?'900':''):''; + fontFamily = (ptype.indexOf('fa-')>=0)?'FontAwesome':(ptype.indexOf('fs-')>=0)?'fhemSVG':'openautomation'; ptype = 'symbol'; } - var attrval2; - var ptc = ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length)).split('-'); - var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; - var type = ptc[0]; - switch (type) { + switch (ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))) { case 'lines': case 'steps': case 'fsteps': @@ -4624,13 +3608,13 @@ var widget_chart = { case 'cubic': case 'quadratic': case 'quadraticSmooth': - attrval={'fill-rule':'evenodd'}; + attrval={}; attrval.class = style; attrval.style = 'stroke-width: ' + strkG.stroke + 'px'; if (strkG.dash && strkG.dash!='none') {attrval.style = attrval.style + '; stroke-dasharray:' + strkG.dash;} // hack for behaviour of Firefox styleV = widget_chart.getStyleRuleValue(classesContainer, 'fill', '.'+style); - attrval.d = widget_chart.getSVGPoints(points, data, min, data.xrange, ptype, (styleV!='none')&&(!nofilldown[k]),uaxis); + attrval.d = widget_chart.getSVGPoints(points, data, min, data.xrange, ptype, (styleV!='none')&&(!data.nofilldown[k]),uaxis); if (styleV) {if(styleV.indexOf("url") >= 0) {attrval.style = attrval.style + '; fill: ' + styleV.slice(0,4)+styleV.slice(-(styleV.length-styleV.lastIndexOf("#"))).replace(/\"/g,'');}} if (ptype.indexOf('_proxy')>0) { // needed for text display in case of logproxy polar attrval2={}; @@ -4682,24 +3666,20 @@ var widget_chart = { if (!aiDone[data.flatUaxis(uaxis)][AI]) { svg.find('line').remove(); - var gridlines, gridlines_left, gridlines_bottom, buttons, tyaxis_prim, tyaxis_sec, txaxis, cxaxis, cgridlines, taxes; + var gridlines, gridlines_left, gridlines_bottom, buttons, tyaxis_prim, tyaxis_sec, txaxis, taxes; if (!gridlines) {gridlines = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!gridlines_left) {gridlines_left = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!gridlines_bottom) {gridlines_bottom = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!buttons) {buttons = widget_chart.createElem('g').attr({'class':'buttons'});} - if (!tyaxis_prim[AI] && data.isPrimary(uaxis)) {tyaxis_prim[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_primary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX(-'+(data.unusedYAxesVisible?data.textWidth_prim.sum(0,AI-1):0)+'px); '+'opacity: '+(data.unusedYAxesVisible?'1':(AI==0?'1':'0'))+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} - if (!tyaxis_sec[AI] && !data.isPrimary(uaxis)) {tyaxis_sec[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_secondary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX('+(data.unusedYAxesVisible?data.textWidth_sec.sum(0,AI-1):0)+'px); '+'opacity: '+(data.unusedYAxesVisible?'1':(AI==0?'1':'0'))+'; '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)});} + if (!tyaxis_prim[AI] && data.isPrimary(uaxis)) {tyaxis_prim[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_primary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX(-'+data.textWidth_prim.sum(0,AI-1)+'px); '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} + if (!tyaxis_sec[AI] && !data.isPrimary(uaxis)) {tyaxis_sec[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_secondary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX('+data.textWidth_sec.sum(0,AI-1)+'px); '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)});} if (!txaxis) {txaxis = widget_chart.createElem('g').attr({'class':'text xaxis','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} - if (!cxaxis) {cxaxis = widget_chart.createElem('g').attr({'style':data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRectXAxis'+data.instance+');'});} - if (!cgridlines) {cgridlines = widget_chart.createElem('g').attr({'style':data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+data.instance+');'});} if (!taxes) {taxes = widget_chart.createElem('g').attr({'class':'text axes'});} tyaxis = (data.isPrimary(uaxis))?tyaxis_prim[AI]:tyaxis_sec[AI]; taxes.append(tyaxis); - taxes.append(cxaxis); - cxaxis.append(txaxis); - gridlines.append(cgridlines); + taxes.append(txaxis); if (ptype.indexOf('_proxy')<0) { // only draw normal gridlines if not _proxy type //y-axis @@ -4807,8 +3787,9 @@ var widget_chart = { buttons.append(zoomMinus); if (data.timeranges != '') { + elem.data(data); var selTimes = widget_chart.createElem('text').attr({ - 'class':'buttons timeranges', + 'class':'buttons', 'x': (noticks)?(5*buttonWidth):(5*buttonWidth)+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -4821,7 +3802,7 @@ var widget_chart = { } var shiftMinus = widget_chart.createElem('text').attr({ - 'class':'buttons shiftminus', + 'class':'buttons', 'x': (noticks)?buttonWidth/2:buttonWidth/2+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -4829,16 +3810,12 @@ var widget_chart = { 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', // 'onclick':'widget_chart.shift(evt, $("svg.basesvg'+instance+'").parent(), 1)', }); - shiftMinus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), 1, false, false, function() { - var baseobject = $("svg.basesvg"+instance).parent(); - var data = baseobject.data; - widget_chart.shiftXContent(baseobject,0,1,0,data); - });}); // jshint ignore:line + shiftMinus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), 1);}); // jshint ignore:line shiftMinus.text(widget_chart.fontNameToUnicode('fa-arrow-circle-left')); buttons.append(shiftMinus); var shiftPlus = widget_chart.createElem('text').attr({ - 'class':'buttons shiftplus', + 'class':'buttons', 'x': (data.basewidth - ((noticks)?(buttonWidth/2):(buttonWidth/2)))+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -4846,11 +3823,7 @@ var widget_chart = { 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', // 'onclick':'widget_chart.shift(evt, $("svg.basesvg'+instance+'").parent(), -1)', }); - shiftPlus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), -1, false, false, function() { - var baseobject = $("svg.basesvg"+instance).parent(); - var data = baseobject.data; - widget_chart.shiftXContent(baseobject,0,1,0,data); - });}); // jshint ignore:line + shiftPlus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), -1);}); // jshint ignore:line shiftPlus.text(widget_chart.fontNameToUnicode('fa-arrow-circle-right')); buttons.append(shiftPlus); @@ -4861,9 +3834,9 @@ var widget_chart = { 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', 'text-anchor':'middle', - 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome' + 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', }); - rotX.text(widget_chart.fontNameToUnicode('fa-long-arrow-'+(ftui.version > '2.7.1'?'alt-':'')+'right')); + rotX.text(widget_chart.fontNameToUnicode('fa-long-arrow-right')); buttons.append(rotX); rotX.on('dblclick',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), -5, 0);}); // jshint ignore:line rotX.on('click',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 5, 0);}); // jshint ignore:line @@ -4892,7 +3865,7 @@ var widget_chart = { 'text-anchor':'middle', 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', }); - rotY.text(widget_chart.fontNameToUnicode('fa-long-arrow-'+(ftui.version > '2.7.1'?'alt-':'')+'up')); + rotY.text(widget_chart.fontNameToUnicode('fa-long-arrow-up')); buttons.append(rotY); rotY.on('dblclick',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 0, -5);}); // jshint ignore:line rotY.on('click',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 0, 5);}); // jshint ignore:line @@ -4906,7 +3879,7 @@ var widget_chart = { 'x': (data.basewidth - ((noticks)?(3.5*buttonWidth):(3.5*buttonWidth)))+'px', 'dy':'1.0em', 'text-anchor':'middle', - 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', + 'style':'font-family: FontAwesome', }); rotY.text(widget_chart.fontNameToUnicode('fa-rotate-left')); gRotY.append(rotY); @@ -4936,7 +3909,6 @@ var widget_chart = { tyaxis.append(text); for (y=ymin_t; y<=max; y+=yticks ){ - if (yticks==0) break; fix = $.isArray(data.yLimits[AI].primary.yticks)?(data.yLimits[AI].primary.yticks[1]?(($.isArray(data.yLimits[AI].primary.yticks[1])?data.yLimits[AI].primary.yticks[1][0]:data.yLimits[AI].primary.yticks[1]) - ymin_t):ymin_t):widget_chart.precision( data.yLimits[AI].primary.yticks ); var line = widget_chart.createElem('line'); p1 = data.transD2W([0,y],uaxis); @@ -4980,19 +3952,6 @@ var widget_chart = { var ysc = (data.isPrimary(uaxis))?(y+data.yLimits[AI].primary.shiftY)/data.yLimits[AI].primary.scaleY:(y+data.yLimits[AI].secondary.shiftY)/data.yLimits[AI].secondary.scaleY; if (parseInt(ysc) == parseFloat(ysc.toFixed(5))) fix = 0; - if ($.isArray(ytary)) { - if (ytary[iyticks] && $.isArray(ytary[iyticks])) { - text.HTML2SVG(ytary[iyticks][1]); - //text.HTML2SVG( widget_chart.formatTicksText(ytary[iyticks][1],fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); - } else { - text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); - } - // exit for loop if yticks array is "finished" now - if(iyticks+1 >= ytary.length) break; - - yticks = $.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks]; - yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY); - /* if ($.isArray(ytary)) { yticks = (ytary.length && ytary.length > iyticks+1)?(($.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks])):yticks; yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY); @@ -5001,7 +3960,6 @@ var widget_chart = { } else { text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); } - */ } else { text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); // text.text( ((fix>-1 && fix<=20) ? parseFloat(ysc.toFixed(fix)) : ysc)+((uaxis=="secondary") ? unit_sec : unit) ); @@ -5040,34 +3998,28 @@ var widget_chart = { } else { textX1.HTML2SVG(tstart.ddmm()); } - if (!cachetype || xtext_offset!=0) txaxis.append(textX1); - textX1.click(function(evt) {widget_chart.resetTime(evt);}); + txaxis.append(textX1); var tx = new Date(tstart); - if (xticksArrayMonths) { - var moffset = tx.getMonth()*($.isArray(xticksArray)?xticksArray.length:12)/12; // care for array length for xticks setup - } else { - var moffset = 0; - } - + var moffset = tx.getMonth()*($.isArray(xticksArray)?xticksArray.length:12)/12; // care for array length for xticks setup x=0; var xold = 0; - var xlast = new Date(tstart); - for ( var xl=(cachetype?0:xticks); xl<=data.xrange+(cachetype?0:0); xl+=xticks ){ // counting up x values (in minutes) + for ( var xl=xticks; xl<=data.xrange; xl+=xticks ){ // counting up x values (in minutes) + tx = new Date(tstart); - var mindex = Math.max(parseInt((xl/xticks+moffset-1)%($.isArray(xticksArray)?xticksArray.length:0)),0); - x = xl==0?0:($.isArray(xticksArray)?(x+(xticksArray[mindex])*60*24):xl); - var xc = x; - if (data.xticks_round !== '' && !$.isArray(xticksArray)) xc = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart,((data.basewidth>200)?3.5:7)); - if (!cachetype && (xc>=data.xrange || xc<=0)) continue; // we have to care that nothing is written beyond end of chart - if (cachetype && (xc>data.xrange+xticks || xc<0)) continue; // we have to care that nothing is written beyond end of chart - - tx.setTime(tstart.getTime() + xc*60*1000); - xtext_offset = widget_chart.getXTOffset(xc,xold,tx,timeformat,data.xtext_offset); - xold = xc; + var mindex = parseInt((xl/xticks+moffset-1)%($.isArray(xticksArray)?xticksArray.length:0)); + x = $.isArray(xticksArray)?(x+(xticksArray[mindex])*60*24):xl; + + if (data.xticks_round !== '') x = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart); + if (x>=data.xrange || x<=0) continue; // we have to care that nothing is written beyond end of chart + + tx.setMinutes(tstart.getMinutes() + x); + xtext_offset = widget_chart.getXTOffset(x,xold,tx,timeformat,data.xtext_offset); + xold = x; + var textX2 = widget_chart.createElem('text'); - posX = data.graphWidth*(xc+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft(); + posX = data.graphWidth*(x+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft(); posY = (((max))/(max-min)*data.graphHeight/100*data.baseheight+data.topOffset)+data.textHeight; textX2.attr({ 'class':'text axes xaxis', @@ -5090,28 +4042,24 @@ var widget_chart = { var textX2Value = (tx.hhmm()=="00:00"||xticks>1440) ? tx.ddmm() : tx.hhmm() ; // if we are at exactly 00:00 of if difference between ticks is larger than a day don't display hours. textX2.HTML2SVG(textX2Value); } - if (!cachetype || (cachetype && ((xc>0) && (xc0?ptype.indexOf('_proxy'):ptype.length)).split('-'); - var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; - var type = ptc[0]; - switch (type) { + switch (ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))) { // add graphs themselves case 'lines': case 'steps': @@ -5227,7 +4169,7 @@ var widget_chart = { polyline.attr('style',polyline.attr('style')+'; opacity: 0.6'); for (i=depth, l=0; i>l; i-=1/dist) { if (i!==0) { - var svg_tmp = svgbase.clone().attr('style',svgbase.attr('style')+'; '+data.DDD.String.Rot+'; '+data.DDD.String.Trans(i,k+1,data.DDD,data.xStrTO,data.yStrTO)); + var svg_tmp = svgbase.clone().attr('style',data.DDD.String.Rot+'; '+data.DDD.String.Trans(i,k+1,data.DDD,data.xStrTO,data.yStrTO)); if (i!=depth && svg_tmp.find('path').attr('style')!==undefined) svg_tmp.find('path').attr('style',svg_tmp.find('path').attr('style').replace(/fill:.*;/,'fill:none; ')); if (i==depth) svg_tmp.find('path').attr('style',svg_tmp.find('path').attr('style')+'; opacity:0.6'); svg_tmp.find('path').attr('id',svg_tmp.find('path').attr('id')+'_'+i); @@ -5319,7 +4261,7 @@ var widget_chart = { g.attr('y0polar',data.transD2W([-data.minx,-data.yLimits[AI].primary.shiftY],'primary')[1]); //var strk = (g.css("stroke-width")) ? parseFloat(g.css("stroke-width").split('px')) : 1; - attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily + ';font-weight:' + fontWeight; + attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily; if (ptype == 'symbol') { for (j=0;j 3?points[j][3]:0; - var scl = points[j].length > 4?points[j][4]:1; - attrval.transform = "translate(" + attrval.x + " " + attrval.y + ") "+"rotate("+angl+")"+" scale("+scl+","+scl+") translate(" + (-attrval.x) + " " + (-attrval.y) + ")"; + attrval.transform = "translate(" + attrval.x + " " + attrval.y + ") scale(1,1) translate(" + (-attrval.x) + " " + (-attrval.y) + ")"; point_new.attr(attrval); point_new.text(symbol); g.append(point_new); @@ -5380,7 +4320,7 @@ var widget_chart = { svg_new.find("[class*=scaleyinvert]").each(function(index) {$(this).attr({'transform':'scale(1 -1)'});}); // generate crosshair container for cursor - var crosshair = widget_chart.createElem('g').attr({'class':'crosshair container','pointer-events':'none','style':'overflow: inherit;'}); + var crosshair = widget_chart.createElem('g').attr({'class':'crosshair','pointer-events':'none','style':'overflow: inherit'}); crosshair.append(widget_chart.createElem('line').attr({'class':'crosshair','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)})); if (data.DDD.Active) crosshair.append(widget_chart.createElem('line').attr({'class':'crosshair','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)})); @@ -5400,8 +4340,7 @@ var widget_chart = { // text element for show/hide of crosshair cursor if (!nobuttons) { - //var cursor_text = widget_chart.createElem('text').attr({'class':'caption'+((data.crosshair)?' active':' inactive'),'x':'51%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); - var cursor_text = widget_chart.createElem('text').attr({'class':'caption cursorbutton'+((data.crosshair)?' active':' inactive'),'x':(noticks)?(data.timeranges!=''?8*fszB:6.5*fszB):(data.timeranges!=''?8*fszB:6.5*fszB)+'px','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); + var cursor_text = widget_chart.createElem('text').attr({'class':'caption'+((data.crosshair)?' active':' inactive'),'x':'51%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); cursor_text.text("Cursor"); cursor_text.on('click', function(event) { if ($(event.delegateTarget).parents("[class^=basesvg]").parent().data('crosshair')) { @@ -5418,9 +4357,7 @@ var widget_chart = { legend_menu.append(cursor_text); } - // register events for crosshair cursor // register events for swipe - if (!data.logProxy) widget_chart.detectSwipe(svg_new.find("rect.chart-background, [id*='graph-']")); - + // register events for crosshair cursor svg_new.find("rect.chart-background, [id*='graph-']").on("mouseenter touchstart",function(event) { widget_chart.checkEvent(event); }); @@ -5436,98 +4373,15 @@ var widget_chart = { // Hack for problem in IE11 with transform of SVG elements browserCaps.doSVGTransformCorrection(svg_new); - // graph source is ready, add it to the page if not in prefetch/cachemode - if (!cachetype) svg_new.appendTo($(theObj)) + // graph source is ready, add it to the page + svg_new.appendTo($(theObj)) .css("width",data.width || data.defaultWidth) .css("height",data.height || data.defaultHeight); - - // calculate and set the cliping rectangle for the x axis - if (!cachetype) { - var first_xtext = svg_new.find('g.text.xaxis').children().first(); - var cl_offset = (first_xtext&&first_xtext.length&&first_xtext.length>0)?first_xtext[0].getBoundingClientRect().width/2:0; - svg_new.find('[id="clipingRectXAxis'+data.instance+'"]').html(widget_chart.getClipPath(data,cl_offset,theObj,3)+widget_chart.getClipPath(data,-cl_offset,theObj,3)); - svg_new.find("svg.chart-primsec").attr("stlye",data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+(data.DDD.prefix=='-moz-'?'Graphs-':'Graphs-')+cachetype+data.instance+'); overflow: visible;'); - } - - if (cachetype) { // we are in prefetch/cache mode, do not use generated SVG graph but copy parts for display of previous and next timeframes when scrolling to main SVG - - var container = widget_chart.createElem('g'); - var offset = (cachetype=='previous'?(0-data.graphArea.width):(0+data.graphArea.width)); - var style; - container.attr('id','baseforDDD-'+cachetype); - //container.attr('style','overflow: inherit; z-index: '+(cachetype=='previous'?'100':'300')+'; '+data.DDD.prefix+'transform: '+data.DDD.String.Scale); - container.attr('style','overflow: inherit; z-index: '+(cachetype=='previous'?'100':'300')+';'+data.DDD.prefix+'transform: '+data.DDD.String.Scale+';'); - container.append(svg_new.find("[id^=cliping]").parent()); - container.find("[id=clipingRect"+data.instance+"]").attr('id','clipingRect-'+cachetype+data.instance); - container.find("[id=clipingRectXAxis"+data.instance+"]").attr('id','clipingRectXAxis-'+cachetype+data.instance); - container.find("[id=clipingRectGraphs"+data.instance+"]").attr('id','clipingRectGraphs-'+cachetype+data.instance); - container.find("[id=clipingRectCursor"+data.instance+"]").attr('id','clipingRectCursor-'+cachetype+data.instance); - style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRectXAxis-'+cachetype+data.instance+'); overflow: visible; ' - container.append(svg_new.find("g.text.xaxis").parent()); - container.find("g.text.xaxis").parent().attr('style',style); - style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect-'+cachetype+data.instance+'); overflow: visible; ' - container.append(svg_new.find("g.chart-gridlines")); - container.find('g.gridlines').attr('style',style); - container.find('line.yticks').remove(); - container.find('line.xaxis').remove(); - container.find('line.yaxis').remove(); - style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+(data.DDD.prefix=='-moz-'?'Graphs-':'Graphs-')+cachetype+data.instance+'); overflow: visible;'; - container.append(svg_new.find("svg.chart-primsec").attr('style',style)); - //svg_new.find('g.lentries').appendTo(container); - svg_new.find('g.lentries').remove(); - cachetype == 'previous' ? - svg_old.find('rect.chart-background').parent().parent().append(container) : - svg_old.find('rect.chart-background').parent().parent().append(container); // needed because position in DOM decides on drawing sequence for SVGs - - var crosshair = svg_old.find('g.crosshair.container').remove(); - //crosshair.children().css('clip-path','url(#clipingRectCursor-'+cachetype+data.instance+')'); - svg_old.find('[id^=baseforDDD]').last().append(crosshair); // need to put cursor at the end of the DOM in order to have it painted on top - - widget_chart.shiftXContent(svg_old,doReset?0:data.offsetX,doReset?1:data.scaleX,doReset?0:data.scaleDeltaX,data); - - if (cachetype == 'previous') { - var xOffset = data.getGraphLeft(); - for (k=0, l=data.graphArea.width+xOffset; k max)) max = this[i]; - } - return max==-Infinity?0:max; - }; } - if (!Array.clone) { Array.prototype.clone = function (reverse) { var i, copy; @@ -5762,27 +4573,23 @@ function init_attr(elem) { // initialize all attributes called from widget init } }; - } // caluclation of min and max values for x axis from dates Date.prototype.isLeapYear = function(inyear) { var year = (inyear!==undefined)?inyear:this.getFullYear(); return (((year%4===0)&&(year%100!==0))||(year%400===0))?true:false; }; - Date.prototype.myGetDaysInMonth = function(inmonth) { + Date.prototype.getDaysInMonth = function(inmonth) { var month = (inmonth!==undefined)?inmonth:this.getMonth(); var year = this.getFullYear() + parseInt((month)/12); return [31,this.isLeapYear(year)?29:28,31,30,31,30,31,31,30,31,30,31][month%12]; }; - Date.prototype.getDateStringFHEM = function() { - return this.getFullYear()+'-'+(this.getMonth()+1).pad()+'-'+this.getDate().pad()+'T'+(this.getHours()-this.stdTimezoneOffset()/60).pad()+':'+this.getMinutes().pad()+':'+this.getSeconds().pad(); - }; Date.prototype.getDaysInMonthSum = function(inmonth) { var month = this.getMonth() var startmonth = (inmonth!==undefined)?(inmonth<=month?inmonth:0):0; var ret = 0; for(var i=startmonth; i<=month; i++) { - ret+=this.myGetDaysInMonth(i); + ret+=this.getDaysInMonth(i); } return ret; }; @@ -5902,7 +4709,7 @@ function init () { // initialization of widget, run at widget creation/reload }); this.defaultHeight = fullheight - siblingheights; } - this.defaultWidth = '93%'; + this.defaultWidth = '93%'; } data.getDefaultSize(elem); @@ -5927,10 +4734,6 @@ function init () { // initialization of widget, run at widget creation/reload var graphsshown_array = elem.data('graphsshown'); for (var k=0, ll=widget_chart.getnGraphs(elem.data()); k Date: Fri, 1 Apr 2022 08:06:34 +0200 Subject: [PATCH 2/3] Revert "Update widget_chart.js" --- www/tablet/js/widget_chart.js | 1865 +++++++++++++++++++++++++++------ 1 file changed, 1531 insertions(+), 334 deletions(-) diff --git a/www/tablet/js/widget_chart.js b/www/tablet/js/widget_chart.js index df0a05ad..706d0b01 100644 --- a/www/tablet/js/widget_chart.js +++ b/www/tablet/js/widget_chart.js @@ -2,8 +2,8 @@ * Copyright (c) 2015-2017 Kurt Eckert * Under MIT License (http://www.opensource.org/licenses/mit-license.php) */ -/* Version 2.7 -/* Compatible FTUI Version >= 2.6 +/* Version 2.11.0 +/* Compatible FTUI Version >= 2.7.2 /* global ftui:true, Modul_widget:true, Powerange:true */ @@ -96,14 +96,26 @@ function depends_chart (){ })(); } + if (!String.stripFormat) { + String.prototype.stripFormat = function() { + return this.replace(/\<(i|b|em|small|strong|mark|del|ins|sub|sup|class)\>/,'').replace(/\<\/(i|b|em|small|strong|mark|del|ins|sub|sup|class)\>/,''); + }; + } + if (!$.fn.HTML2SVG) { $.fn.HTML2SVG = function(text,delfirst) { + var isIE = navigator.userAgent.match(/Trident/); this.each(function() { var convertedText = widget_chart.getFormattedText(text); - if (convertedText.search(/tspan/) < 0) convertedText = '' + convertedText + ''; - var elem = this; - if (delfirst) $(elem).empty(); - $(elem).html(convertedText); + if (convertedText.search(/^\'; + var elem = $(this); + if (delfirst) elem.empty(); + if (isIE) { + convertedText = convertedText.replace(/\]*\>/g,'').replace(/\<\/tspan\>/g,''); + elem.text(convertedText); + } else { + elem.html(convertedText); + } }); }; } @@ -190,6 +202,7 @@ var widget_chart = { initialized : [], LOGTYPE : 'console', logtext : '', + gBCaps : undefined, doLog: function(func,info,level) { // print log commands to console if DEBUG is set if (widget_chart.LOGTYPE == 'console') { @@ -228,10 +241,11 @@ var widget_chart = { return isIE; }, fontNameToUnicode: function(name) { - var FONT_AWESOME = {"fa-500px":"\uf26e","fa-adjust":"\uf042","fa-adn":"\uf170","fa-align-center":"\uf037","fa-align-justify":"\uf039","fa-align-left":"\uf036","fa-align-right":"\uf038","fa-amazon":"\uf270","fa-ambulance":"\uf0f9","fa-anchor":"\uf13d","fa-android":"\uf17b","fa-angellist":"\uf209","fa-angle-double-down":"\uf103","fa-angle-double-left":"\uf100","fa-angle-double-right":"\uf101","fa-angle-double-up":"\uf102","fa-angle-down":"\uf107","fa-angle-left":"\uf104","fa-angle-right":"\uf105","fa-angle-up":"\uf106","fa-apple":"\uf179","fa-archive":"\uf187","fa-area-chart":"\uf1fe","fa-arrow-circle-down":"\uf0ab","fa-arrow-circle-left":"\uf0a8","fa-arrow-circle-o-down":"\uf01a","fa-arrow-circle-o-left":"\uf190","fa-arrow-circle-o-right":"\uf18e","fa-arrow-circle-o-up":"\uf01b","fa-arrow-circle-right":"\uf0a9","fa-arrow-circle-up":"\uf0aa","fa-arrow-down":"\uf063","fa-arrow-left":"\uf060","fa-arrow-right":"\uf061","fa-arrow-up":"\uf062","fa-arrows":"\uf047","fa-arrows-alt":"\uf0b2","fa-arrows-h":"\uf07e","fa-arrows-v":"\uf07d","fa-asterisk":"\uf069","fa-at":"\uf1fa","fa-automobile":"\uf1b9","fa-backward":"\uf04a","fa-balance-scale":"\uf24e","fa-ban":"\uf05e","fa-bank":"\uf19c","fa-bar-chart":"\uf080","fa-bar-chart-o":"\uf080","fa-barcode":"\uf02a","fa-bars":"\uf0c9","fa-battery-0":"\uf244","fa-battery-1":"\uf243","fa-battery-2":"\uf242","fa-battery-3":"\uf241","fa-battery-4":"\uf240","fa-battery-empty":"\uf244","fa-battery-full":"\uf240","fa-battery-half":"\uf242","fa-battery-quarter":"\uf243","fa-battery-three-quarters":"\uf241","fa-bed":"\uf236","fa-beer":"\uf0fc","fa-behance":"\uf1b4","fa-behance-square":"\uf1b5","fa-bell":"\uf0f3","fa-bell-o":"\uf0a2","fa-bell-slash":"\uf1f6","fa-bell-slash-o":"\uf1f7","fa-bicycle":"\uf206","fa-binoculars":"\uf1e5","fa-birthday-cake":"\uf1fd","fa-bitbucket":"\uf171","fa-bitbucket-square":"\uf172","fa-bitcoin":"\uf15a","fa-black-tie":"\uf27e","fa-bold":"\uf032","fa-bolt":"\uf0e7","fa-bomb":"\uf1e2","fa-book":"\uf02d","fa-bookmark":"\uf02e","fa-bookmark-o":"\uf097","fa-briefcase":"\uf0b1","fa-btc":"\uf15a","fa-bug":"\uf188","fa-building":"\uf1ad","fa-building-o":"\uf0f7","fa-bullhorn":"\uf0a1","fa-bullseye":"\uf140","fa-bus":"\uf207","fa-buysellads":"\uf20d","fa-cab":"\uf1ba","fa-calculator":"\uf1ec","fa-calendar":"\uf073","fa-calendar-check-o":"\uf274","fa-calendar-minus-o":"\uf272","fa-calendar-o":"\uf133","fa-calendar-plus-o":"\uf271","fa-calendar-times-o":"\uf273","fa-camera":"\uf030","fa-camera-retro":"\uf083","fa-car":"\uf1b9","fa-caret-down":"\uf0d7","fa-caret-left":"\uf0d9","fa-caret-right":"\uf0da","fa-caret-square-o-down":"\uf150","fa-caret-square-o-left":"\uf191","fa-caret-square-o-right":"\uf152","fa-caret-square-o-up":"\uf151","fa-caret-up":"\uf0d8","fa-cart-arrow-down":"\uf218","fa-cart-plus":"\uf217","fa-cc":"\uf20a","fa-cc-amex":"\uf1f3","fa-cc-diners-club":"\uf24c","fa-cc-discover":"\uf1f2","fa-cc-jcb":"\uf24b","fa-cc-mastercard":"\uf1f1","fa-cc-paypal":"\uf1f4","fa-cc-stripe":"\uf1f5","fa-cc-visa":"\uf1f0","fa-certificate":"\uf0a3","fa-chain":"\uf0c1","fa-chain-broken":"\uf127","fa-check":"\uf00c","fa-check-circle":"\uf058","fa-check-circle-o":"\uf05d","fa-check-square":"\uf14a","fa-check-square-o":"\uf046","fa-chevron-circle-down":"\uf13a","fa-chevron-circle-left":"\uf137","fa-chevron-circle-right":"\uf138","fa-chevron-circle-up":"\uf139","fa-chevron-down":"\uf078","fa-chevron-left":"\uf053","fa-chevron-right":"\uf054","fa-chevron-up":"\uf077","fa-child":"\uf1ae","fa-chrome":"\uf268","fa-circle":"\uf111","fa-circle-o":"\uf10c","fa-circle-o-notch":"\uf1ce","fa-circle-thin":"\uf1db","fa-clipboard":"\uf0ea","fa-clock-o":"\uf017","fa-clone":"\uf24d","fa-close":"\uf00d","fa-cloud":"\uf0c2","fa-cloud-download":"\uf0ed","fa-cloud-upload":"\uf0ee","fa-cny":"\uf157","fa-code":"\uf121","fa-code-fork":"\uf126","fa-codepen":"\uf1cb","fa-coffee":"\uf0f4","fa-cog":"\uf013","fa-cogs":"\uf085","fa-columns":"\uf0db","fa-comment":"\uf075","fa-comment-o":"\uf0e5","fa-commenting":"\uf27a","fa-commenting-o":"\uf27b","fa-comments":"\uf086","fa-comments-o":"\uf0e6","fa-compass":"\uf14e","fa-compress":"\uf066","fa-connectdevelop":"\uf20e","fa-contao":"\uf26d","fa-copy":"\uf0c5","fa-copyright":"\uf1f9","fa-creative-commons":"\uf25e","fa-credit-card":"\uf09d","fa-crop":"\uf125","fa-crosshairs":"\uf05b","fa-css3":"\uf13c","fa-cube":"\uf1b2","fa-cubes":"\uf1b3","fa-cut":"\uf0c4","fa-cutlery":"\uf0f5","fa-dashboard":"\uf0e4","fa-dashcube":"\uf210","fa-database":"\uf1c0","fa-dedent":"\uf03b","fa-delicious":"\uf1a5","fa-desktop":"\uf108","fa-deviantart":"\uf1bd","fa-diamond":"\uf219","fa-digg":"\uf1a6","fa-dollar":"\uf155","fa-dot-circle-o":"\uf192","fa-download":"\uf019","fa-dribbble":"\uf17d","fa-dropbox":"\uf16b","fa-drupal":"\uf1a9","fa-edit":"\uf044","fa-eject":"\uf052","fa-ellipsis-h":"\uf141","fa-ellipsis-v":"\uf142","fa-empire":"\uf1d1","fa-envelope":"\uf0e0","fa-envelope-o":"\uf003","fa-envelope-square":"\uf199","fa-eraser":"\uf12d","fa-eur":"\uf153","fa-euro":"\uf153","fa-exchange":"\uf0ec","fa-exclamation":"\uf12a","fa-exclamation-circle":"\uf06a","fa-exclamation-triangle":"\uf071","fa-expand":"\uf065","fa-expeditedssl":"\uf23e","fa-external-link":"\uf08e","fa-external-link-square":"\uf14c","fa-eye":"\uf06e","fa-eye-slash":"\uf070","fa-eyedropper":"\uf1fb","fa-facebook":"\uf09a","fa-facebook-f":"\uf09a","fa-facebook-official":"\uf230","fa-facebook-square":"\uf082","fa-fast-backward":"\uf049","fa-fast-forward":"\uf050","fa-fax":"\uf1ac","fa-feed":"\uf09e","fa-female":"\uf182","fa-fighter-jet":"\uf0fb","fa-file":"\uf15b","fa-file-archive-o":"\uf1c6","fa-file-audio-o":"\uf1c7","fa-file-code-o":"\uf1c9","fa-file-excel-o":"\uf1c3","fa-file-image-o":"\uf1c5","fa-file-movie-o":"\uf1c8","fa-file-o":"\uf016","fa-file-pdf-o":"\uf1c1","fa-file-photo-o":"\uf1c5","fa-file-picture-o":"\uf1c5","fa-file-powerpoint-o":"\uf1c4","fa-file-sound-o":"\uf1c7","fa-file-text":"\uf15c","fa-file-text-o":"\uf0f6","fa-file-video-o":"\uf1c8","fa-file-word-o":"\uf1c2","fa-file-zip-o":"\uf1c6","fa-files-o":"\uf0c5","fa-film":"\uf008","fa-filter":"\uf0b0","fa-fire":"\uf06d","fa-fire-extinguisher":"\uf134","fa-firefox":"\uf269","fa-flag":"\uf024","fa-flag-checkered":"\uf11e","fa-flag-o":"\uf11d","fa-flash":"\uf0e7","fa-flask":"\uf0c3","fa-flickr":"\uf16e","fa-floppy-o":"\uf0c7","fa-folder":"\uf07b","fa-folder-o":"\uf114","fa-folder-open":"\uf07c","fa-folder-open-o":"\uf115","fa-font":"\uf031","fa-fonticons":"\uf280","fa-forumbee":"\uf211","fa-forward":"\uf04e","fa-foursquare":"\uf180","fa-frown-o":"\uf119","fa-futbol-o":"\uf1e3","fa-gamepad":"\uf11b","fa-gavel":"\uf0e3","fa-gbp":"\uf154","fa-ge":"\uf1d1","fa-gear":"\uf013","fa-gears":"\uf085","fa-genderless":"\uf22d","fa-get-pocket":"\uf265","fa-gg":"\uf260","fa-gg-circle":"\uf261","fa-gift":"\uf06b","fa-git":"\uf1d3","fa-git-square":"\uf1d2","fa-github":"\uf09b","fa-github-alt":"\uf113","fa-github-square":"\uf092","fa-gittip":"\uf184","fa-glass":"\uf000","fa-globe":"\uf0ac","fa-google":"\uf1a0","fa-google-plus":"\uf0d5","fa-google-plus-square":"\uf0d4","fa-google-wallet":"\uf1ee","fa-graduation-cap":"\uf19d","fa-gratipay":"\uf184","fa-group":"\uf0c0","fa-h-square":"\uf0fd","fa-hacker-news":"\uf1d4","fa-hand-grab-o":"\uf255","fa-hand-lizard-o":"\uf258","fa-hand-o-down":"\uf0a7","fa-hand-o-left":"\uf0a5","fa-hand-o-right":"\uf0a4","fa-hand-o-up":"\uf0a6","fa-hand-paper-o":"\uf256","fa-hand-peace-o":"\uf25b","fa-hand-pointer-o":"\uf25a","fa-hand-rock-o":"\uf255","fa-hand-scissors-o":"\uf257","fa-hand-spock-o":"\uf259","fa-hand-stop-o":"\uf256","fa-hdd-o":"\uf0a0","fa-header":"\uf1dc","fa-headphones":"\uf025","fa-heart":"\uf004","fa-heart-o":"\uf08a","fa-heartbeat":"\uf21e","fa-history":"\uf1da","fa-home":"\uf015","fa-hospital-o":"\uf0f8","fa-hotel":"\uf236","fa-hourglass":"\uf254","fa-hourglass-1":"\uf251","fa-hourglass-2":"\uf252","fa-hourglass-3":"\uf253","fa-hourglass-end":"\uf253","fa-hourglass-half":"\uf252","fa-hourglass-o":"\uf250","fa-hourglass-start":"\uf251","fa-houzz":"\uf27c","fa-html5":"\uf13b","fa-i-cursor":"\uf246","fa-ils":"\uf20b","fa-image":"\uf03e","fa-inbox":"\uf01c","fa-indent":"\uf03c","fa-industry":"\uf275","fa-info":"\uf129","fa-info-circle":"\uf05a","fa-inr":"\uf156","fa-instagram":"\uf16d","fa-institution":"\uf19c","fa-internet-explorer":"\uf26b","fa-intersex":"\uf224","fa-ioxhost":"\uf208","fa-italic":"\uf033","fa-joomla":"\uf1aa","fa-jpy":"\uf157","fa-jsfiddle":"\uf1cc","fa-key":"\uf084","fa-keyboard-o":"\uf11c","fa-krw":"\uf159","fa-language":"\uf1ab","fa-laptop":"\uf109","fa-lastfm":"\uf202","fa-lastfm-square":"\uf203","fa-leaf":"\uf06c","fa-leanpub":"\uf212","fa-legal":"\uf0e3","fa-lemon-o":"\uf094","fa-level-down":"\uf149","fa-level-up":"\uf148","fa-life-bouy":"\uf1cd","fa-life-buoy":"\uf1cd","fa-life-ring":"\uf1cd","fa-life-saver":"\uf1cd","fa-lightbulb-o":"\uf0eb","fa-line-chart":"\uf201","fa-link":"\uf0c1","fa-linkedin":"\uf0e1","fa-linkedin-square":"\uf08c","fa-linux":"\uf17c","fa-list":"\uf03a","fa-list-alt":"\uf022","fa-list-ol":"\uf0cb","fa-list-ul":"\uf0ca","fa-location-arrow":"\uf124","fa-lock":"\uf023","fa-long-arrow-down":"\uf175","fa-long-arrow-left":"\uf177","fa-long-arrow-right":"\uf178","fa-long-arrow-up":"\uf176","fa-magic":"\uf0d0","fa-magnet":"\uf076","fa-mail-forward":"\uf064","fa-mail-reply":"\uf112","fa-mail-reply-all":"\uf122","fa-male":"\uf183","fa-map":"\uf279","fa-map-marker":"\uf041","fa-map-o":"\uf278","fa-map-pin":"\uf276","fa-map-signs":"\uf277","fa-mars":"\uf222","fa-mars-double":"\uf227","fa-mars-stroke":"\uf229","fa-mars-stroke-h":"\uf22b","fa-mars-stroke-v":"\uf22a","fa-maxcdn":"\uf136","fa-meanpath":"\uf20c","fa-medium":"\uf23a","fa-medkit":"\uf0fa","fa-meh-o":"\uf11a","fa-mercury":"\uf223","fa-microphone":"\uf130","fa-microphone-slash":"\uf131","fa-minus":"\uf068","fa-minus-circle":"\uf056","fa-minus-square":"\uf146","fa-minus-square-o":"\uf147","fa-mobile":"\uf10b","fa-mobile-phone":"\uf10b","fa-money":"\uf0d6","fa-moon-o":"\uf186","fa-mortar-board":"\uf19d","fa-motorcycle":"\uf21c","fa-mouse-pointer":"\uf245","fa-music":"\uf001","fa-navicon":"\uf0c9","fa-neuter":"\uf22c","fa-newspaper-o":"\uf1ea","fa-object-group":"\uf247","fa-object-ungroup":"\uf248","fa-odnoklassniki":"\uf263","fa-odnoklassniki-square":"\uf264","fa-opencart":"\uf23d","fa-openid":"\uf19b","fa-opera":"\uf26a","fa-optin-monster":"\uf23c","fa-outdent":"\uf03b","fa-pagelines":"\uf18c","fa-paint-brush":"\uf1fc","fa-paper-plane":"\uf1d8","fa-paper-plane-o":"\uf1d9","fa-paperclip":"\uf0c6","fa-paragraph":"\uf1dd","fa-paste":"\uf0ea","fa-pause":"\uf04c","fa-paw":"\uf1b0","fa-paypal":"\uf1ed","fa-pencil":"\uf040","fa-pencil-square":"\uf14b","fa-pencil-square-o":"\uf044","fa-phone":"\uf095","fa-phone-square":"\uf098","fa-photo":"\uf03e","fa-picture-o":"\uf03e","fa-pie-chart":"\uf200","fa-pied-piper":"\uf1a7","fa-pied-piper-alt":"\uf1a8","fa-pinterest":"\uf0d2","fa-pinterest-p":"\uf231","fa-pinterest-square":"\uf0d3","fa-plane":"\uf072","fa-play":"\uf04b","fa-play-circle":"\uf144","fa-play-circle-o":"\uf01d","fa-plug":"\uf1e6","fa-plus":"\uf067","fa-plus-circle":"\uf055","fa-plus-square":"\uf0fe","fa-plus-square-o":"\uf196","fa-power-off":"\uf011","fa-print":"\uf02f","fa-puzzle-piece":"\uf12e","fa-qq":"\uf1d6","fa-qrcode":"\uf029","fa-question":"\uf128","fa-question-circle":"\uf059","fa-quote-left":"\uf10d","fa-quote-right":"\uf10e","fa-ra":"\uf1d0","fa-random":"\uf074","fa-rebel":"\uf1d0","fa-recycle":"\uf1b8","fa-reddit":"\uf1a1","fa-reddit-square":"\uf1a2","fa-refresh":"\uf021","fa-registered":"\uf25d","fa-remove":"\uf00d","fa-renren":"\uf18b","fa-reorder":"\uf0c9","fa-repeat":"\uf01e","fa-reply":"\uf112","fa-reply-all":"\uf122","fa-retweet":"\uf079","fa-rmb":"\uf157","fa-road":"\uf018","fa-rocket":"\uf135","fa-rotate-left":"\uf0e2","fa-rotate-right":"\uf01e","fa-rouble":"\uf158","fa-rss":"\uf09e","fa-rss-square":"\uf143","fa-rub":"\uf158","fa-ruble":"\uf158","fa-rupee":"\uf156","fa-safari":"\uf267","fa-save":"\uf0c7","fa-scissors":"\uf0c4","fa-search":"\uf002","fa-search-minus":"\uf010","fa-search-plus":"\uf00e","fa-sellsy":"\uf213","fa-send":"\uf1d8","fa-send-o":"\uf1d9","fa-server":"\uf233","fa-share":"\uf064","fa-share-alt":"\uf1e0","fa-share-alt-square":"\uf1e1","fa-share-square":"\uf14d","fa-share-square-o":"\uf045","fa-shekel":"\uf20b","fa-sheqel":"\uf20b","fa-shield":"\uf132","fa-ship":"\uf21a","fa-shirtsinbulk":"\uf214","fa-shopping-cart":"\uf07a","fa-sign-in":"\uf090","fa-sign-out":"\uf08b","fa-signal":"\uf012","fa-simplybuilt":"\uf215","fa-sitemap":"\uf0e8","fa-skyatlas":"\uf216","fa-skype":"\uf17e","fa-slack":"\uf198","fa-sliders":"\uf1de","fa-slideshare":"\uf1e7","fa-smile-o":"\uf118","fa-soccer-ball-o":"\uf1e3","fa-sort":"\uf0dc","fa-sort-alpha-asc":"\uf15d","fa-sort-alpha-desc":"\uf15e","fa-sort-amount-asc":"\uf160","fa-sort-amount-desc":"\uf161","fa-sort-asc":"\uf0de","fa-sort-desc":"\uf0dd","fa-sort-down":"\uf0dd","fa-sort-numeric-asc":"\uf162","fa-sort-numeric-desc":"\uf163","fa-sort-up":"\uf0de","fa-soundcloud":"\uf1be","fa-space-shuttle":"\uf197","fa-spinner":"\uf110","fa-spoon":"\uf1b1","fa-spotify":"\uf1bc","fa-square":"\uf0c8","fa-square-o":"\uf096","fa-stack-exchange":"\uf18d","fa-stack-overflow":"\uf16c","fa-star":"\uf005","fa-star-half":"\uf089","fa-star-half-empty":"\uf123","fa-star-half-full":"\uf123","fa-star-half-o":"\uf123","fa-star-o":"\uf006","fa-steam":"\uf1b6","fa-steam-square":"\uf1b7","fa-step-backward":"\uf048","fa-step-forward":"\uf051","fa-stethoscope":"\uf0f1","fa-sticky-note":"\uf249","fa-sticky-note-o":"\uf24a","fa-stop":"\uf04d","fa-street-view":"\uf21d","fa-strikethrough":"\uf0cc","fa-stumbleupon":"\uf1a4","fa-stumbleupon-circle":"\uf1a3","fa-subscript":"\uf12c","fa-subway":"\uf239","fa-suitcase":"\uf0f2","fa-sun-o":"\uf185","fa-superscript":"\uf12b","fa-support":"\uf1cd","fa-table":"\uf0ce","fa-tablet":"\uf10a","fa-tachometer":"\uf0e4","fa-tag":"\uf02b","fa-tags":"\uf02c","fa-tasks":"\uf0ae","fa-taxi":"\uf1ba","fa-television":"\uf26c","fa-tencent-weibo":"\uf1d5","fa-terminal":"\uf120","fa-text-height":"\uf034","fa-text-width":"\uf035","fa-th":"\uf00a","fa-th-large":"\uf009","fa-th-list":"\uf00b","fa-thumb-tack":"\uf08d","fa-thumbs-down":"\uf165","fa-thumbs-o-down":"\uf088","fa-thumbs-o-up":"\uf087","fa-thumbs-up":"\uf164","fa-ticket":"\uf145","fa-times":"\uf00d","fa-times-circle":"\uf057","fa-times-circle-o":"\uf05c","fa-tint":"\uf043","fa-toggle-down":"\uf150","fa-toggle-left":"\uf191","fa-toggle-off":"\uf204","fa-toggle-on":"\uf205","fa-toggle-right":"\uf152","fa-toggle-up":"\uf151","fa-trademark":"\uf25c","fa-train":"\uf238","fa-transgender":"\uf224","fa-transgender-alt":"\uf225","fa-trash":"\uf1f8","fa-trash-o":"\uf014","fa-tree":"\uf1bb","fa-trello":"\uf181","fa-tripadvisor":"\uf262","fa-trophy":"\uf091","fa-truck":"\uf0d1","fa-try":"\uf195","fa-tty":"\uf1e4","fa-tumblr":"\uf173","fa-tumblr-square":"\uf174","fa-turkish-lira":"\uf195","fa-tv":"\uf26c","fa-twitch":"\uf1e8","fa-twitter":"\uf099","fa-twitter-square":"\uf081","fa-umbrella":"\uf0e9","fa-underline":"\uf0cd","fa-undo":"\uf0e2","fa-university":"\uf19c","fa-unlink":"\uf127","fa-unlock":"\uf09c","fa-unlock-alt":"\uf13e","fa-unsorted":"\uf0dc","fa-upload":"\uf093","fa-usd":"\uf155","fa-user":"\uf007","fa-user-md":"\uf0f0","fa-user-plus":"\uf234","fa-user-secret":"\uf21b","fa-user-times":"\uf235","fa-users":"\uf0c0","fa-venus":"\uf221","fa-venus-double":"\uf226","fa-venus-mars":"\uf228","fa-viacoin":"\uf237","fa-video-camera":"\uf03d","fa-vimeo":"\uf27d","fa-vimeo-square":"\uf194","fa-vine":"\uf1ca","fa-vk":"\uf189","fa-volume-down":"\uf027","fa-volume-off":"\uf026","fa-volume-up":"\uf028","fa-warning":"\uf071","fa-wechat":"\uf1d7","fa-weibo":"\uf18a","fa-weixin":"\uf1d7","fa-whatsapp":"\uf232","fa-wheelchair":"\uf193","fa-wifi":"\uf1eb","fa-wikipedia-w":"\uf266","fa-windows":"\uf17a","fa-won":"\uf159","fa-wordpress":"\uf19a","fa-wrench":"\uf0ad","fa-xing":"\uf168","fa-xing-square":"\uf169","fa-y-combinator":"\uf23b","fa-y-combinator-square":"\uf1d4","fa-yahoo":"\uf19e","fa-yc":"\uf23b","fa-yc-square":"\uf1d4","fa-yelp":"\uf1e9","fa-yen":"\uf157","fa-youtube":"\uf167","fa-youtube-play":"\uf16a","fa-youtube-square":"\uf166"}; + var FONT_AWESOME = {"fa-500px":"\uf26e","fa-adjust":"\uf042","fa-adn":"\uf170","fa-align-center":"\uf037","fa-align-justify":"\uf039","fa-align-left":"\uf036","fa-align-right":"\uf038","fa-amazon":"\uf270","fa-ambulance":"\uf0f9","fa-anchor":"\uf13d","fa-android":"\uf17b","fa-angellist":"\uf209","fa-angle-double-down":"\uf103","fa-angle-double-left":"\uf100","fa-angle-double-right":"\uf101","fa-angle-double-up":"\uf102","fa-angle-down":"\uf107","fa-angle-left":"\uf104","fa-angle-right":"\uf105","fa-angle-up":"\uf106","fa-apple":"\uf179","fa-archive":"\uf187","fa-area-chart":"\uf1fe","fa-arrow-circle-down":"\uf0ab","fa-arrow-circle-left":"\uf0a8","fa-arrow-circle-o-down":"\uf01a","fa-arrow-circle-o-left":"\uf190","fa-arrow-circle-o-right":"\uf18e","fa-arrow-circle-o-up":"\uf01b","fa-arrow-circle-right":"\uf0a9","fa-arrow-circle-up":"\uf0aa","fa-arrow-down":"\uf063","fa-arrow-left":"\uf060","fa-arrow-right":"\uf061","fa-arrow-up":"\uf062","fa-arrows":"\uf047","fa-arrows-alt":"\uf0b2","fa-arrows-h":"\uf07e","fa-arrows-v":"\uf07d","fa-asterisk":"\uf069","fa-at":"\uf1fa","fa-automobile":"\uf1b9","fa-backward":"\uf04a","fa-balance-scale":"\uf24e","fa-ban":"\uf05e","fa-bank":"\uf19c","fa-bar-chart":"\uf080","fa-bar-chart-o":"\uf080","fa-barcode":"\uf02a","fa-bars":"\uf0c9","fa-battery-0":"\uf244","fa-battery-1":"\uf243","fa-battery-2":"\uf242","fa-battery-3":"\uf241","fa-battery-4":"\uf240","fa-battery-empty":"\uf244","fa-battery-full":"\uf240","fa-battery-half":"\uf242","fa-battery-quarter":"\uf243","fa-battery-three-quarters":"\uf241","fa-bed":"\uf236","fa-beer":"\uf0fc","fa-behance":"\uf1b4","fa-behance-square":"\uf1b5","fa-bell":"\uf0f3","fa-bell-o":"\uf0a2","fa-bell-slash":"\uf1f6","fa-bell-slash-o":"\uf1f7","fa-bicycle":"\uf206","fa-binoculars":"\uf1e5","fa-birthday-cake":"\uf1fd","fa-bitbucket":"\uf171","fa-bitbucket-square":"\uf172","fa-bitcoin":"\uf15a","fa-black-tie":"\uf27e","fa-bold":"\uf032","fa-bolt":"\uf0e7","fa-bomb":"\uf1e2","fa-book":"\uf02d","fa-bookmark":"\uf02e","fa-bookmark-o":"\uf097","fa-briefcase":"\uf0b1","fa-btc":"\uf15a","fa-bug":"\uf188","fa-building":"\uf1ad","fa-building-o":"\uf0f7","fa-bullhorn":"\uf0a1","fa-bullseye":"\uf140","fa-bus":"\uf207","fa-buysellads":"\uf20d","fa-cab":"\uf1ba","fa-calculator":"\uf1ec","fa-calendar":"\uf073","fa-calendar-check-o":"\uf274","fa-calendar-minus-o":"\uf272","fa-calendar-o":"\uf133","fa-calendar-plus-o":"\uf271","fa-calendar-times-o":"\uf273","fa-camera":"\uf030","fa-camera-retro":"\uf083","fa-car":"\uf1b9","fa-caret-down":"\uf0d7","fa-caret-left":"\uf0d9","fa-caret-right":"\uf0da","fa-caret-square-o-down":"\uf150","fa-caret-square-o-left":"\uf191","fa-caret-square-o-right":"\uf152","fa-caret-square-o-up":"\uf151","fa-caret-up":"\uf0d8","fa-cart-arrow-down":"\uf218","fa-cart-plus":"\uf217","fa-cc":"\uf20a","fa-cc-amex":"\uf1f3","fa-cc-diners-club":"\uf24c","fa-cc-discover":"\uf1f2","fa-cc-jcb":"\uf24b","fa-cc-mastercard":"\uf1f1","fa-cc-paypal":"\uf1f4","fa-cc-stripe":"\uf1f5","fa-cc-visa":"\uf1f0","fa-certificate":"\uf0a3","fa-chain":"\uf0c1","fa-chain-broken":"\uf127","fa-check":"\uf00c","fa-check-circle":"\uf058","fa-check-circle-o":"\uf05d","fa-check-square":"\uf14a","fa-check-square-o":"\uf046","fa-chevron-circle-down":"\uf13a","fa-chevron-circle-left":"\uf137","fa-chevron-circle-right":"\uf138","fa-chevron-circle-up":"\uf139","fa-chevron-down":"\uf078","fa-chevron-left":"\uf053","fa-chevron-right":"\uf054","fa-chevron-up":"\uf077","fa-child":"\uf1ae","fa-chrome":"\uf268","fa-circle":"\uf111","fa-circle-o":"\uf10c","fa-circle-o-notch":"\uf1ce","fa-circle-thin":"\uf1db","fa-clipboard":"\uf0ea","fa-clock-o":"\uf017","fa-clone":"\uf24d","fa-close":"\uf00d","fa-cloud":"\uf0c2","fa-cloud-download":"\uf0ed","fa-cloud-upload":"\uf0ee","fa-cny":"\uf157","fa-code":"\uf121","fa-code-fork":"\uf126","fa-codepen":"\uf1cb","fa-coffee":"\uf0f4","fa-cog":"\uf013","fa-cogs":"\uf085","fa-columns":"\uf0db","fa-comment":"\uf075","fa-comment-o":"\uf0e5","fa-commenting":"\uf27a","fa-commenting-o":"\uf27b","fa-comments":"\uf086","fa-comments-o":"\uf0e6","fa-compass":"\uf14e","fa-compress":"\uf066","fa-connectdevelop":"\uf20e","fa-contao":"\uf26d","fa-copy":"\uf0c5","fa-copyright":"\uf1f9","fa-creative-commons":"\uf25e","fa-credit-card":"\uf09d","fa-crop":"\uf125","fa-crosshairs":"\uf05b","fa-css3":"\uf13c","fa-cube":"\uf1b2","fa-cubes":"\uf1b3","fa-cut":"\uf0c4","fa-cutlery":"\uf0f5","fa-dashboard":"\uf0e4","fa-dashcube":"\uf210","fa-database":"\uf1c0","fa-dedent":"\uf03b","fa-delicious":"\uf1a5","fa-desktop":"\uf108","fa-deviantart":"\uf1bd","fa-diamond":"\uf219","fa-digg":"\uf1a6","fa-dollar":"\uf155","fa-dot-circle-o":"\uf192","fa-download":"\uf019","fa-dribbble":"\uf17d","fa-dropbox":"\uf16b","fa-drupal":"\uf1a9","fa-edit":"\uf044","fa-eject":"\uf052","fa-ellipsis-h":"\uf141","fa-ellipsis-v":"\uf142","fa-empire":"\uf1d1","fa-envelope":"\uf0e0","fa-envelope-o":"\uf003","fa-envelope-square":"\uf199","fa-eraser":"\uf12d","fa-eur":"\uf153","fa-euro":"\uf153","fa-exchange":"\uf0ec","fa-exclamation":"\uf12a","fa-exclamation-circle":"\uf06a","fa-exclamation-triangle":"\uf071","fa-expand":"\uf065","fa-expeditedssl":"\uf23e","fa-external-link":"\uf08e","fa-external-link-square":"\uf14c","fa-eye":"\uf06e","fa-eye-slash":"\uf070","fa-eyedropper":"\uf1fb","fa-facebook":"\uf09a","fa-facebook-f":"\uf09a","fa-facebook-official":"\uf230","fa-facebook-square":"\uf082","fa-fast-backward":"\uf049","fa-fast-forward":"\uf050","fa-fax":"\uf1ac","fa-feed":"\uf09e","fa-female":"\uf182","fa-fighter-jet":"\uf0fb","fa-file":"\uf15b","fa-file-archive-o":"\uf1c6","fa-file-audio-o":"\uf1c7","fa-file-code-o":"\uf1c9","fa-file-excel-o":"\uf1c3","fa-file-image-o":"\uf1c5","fa-file-movie-o":"\uf1c8","fa-file-o":"\uf016","fa-file-pdf-o":"\uf1c1","fa-file-photo-o":"\uf1c5","fa-file-picture-o":"\uf1c5","fa-file-powerpoint-o":"\uf1c4","fa-file-sound-o":"\uf1c7","fa-file-text":"\uf15c","fa-file-text-o":"\uf0f6","fa-file-video-o":"\uf1c8","fa-file-word-o":"\uf1c2","fa-file-zip-o":"\uf1c6","fa-files-o":"\uf0c5","fa-film":"\uf008","fa-filter":"\uf0b0","fa-fire":"\uf06d","fa-fire-extinguisher":"\uf134","fa-firefox":"\uf269","fa-flag":"\uf024","fa-flag-checkered":"\uf11e","fa-flag-o":"\uf11d","fa-flash":"\uf0e7","fa-flask":"\uf0c3","fa-flickr":"\uf16e","fa-floppy-o":"\uf0c7","fa-folder":"\uf07b","fa-folder-o":"\uf114","fa-folder-open":"\uf07c","fa-folder-open-o":"\uf115","fa-font":"\uf031","fa-fonticons":"\uf280","fa-forumbee":"\uf211","fa-forward":"\uf04e","fa-foursquare":"\uf180","fa-frown-o":"\uf119","fa-futbol-o":"\uf1e3","fa-gamepad":"\uf11b","fa-gavel":"\uf0e3","fa-gbp":"\uf154","fa-ge":"\uf1d1","fa-gear":"\uf013","fa-gears":"\uf085","fa-genderless":"\uf22d","fa-get-pocket":"\uf265","fa-gg":"\uf260","fa-gg-circle":"\uf261","fa-gift":"\uf06b","fa-git":"\uf1d3","fa-git-square":"\uf1d2","fa-github":"\uf09b","fa-github-alt":"\uf113","fa-github-square":"\uf092","fa-gittip":"\uf184","fa-glass":"\uf000","fa-globe":"\uf0ac","fa-google":"\uf1a0","fa-google-plus":"\uf0d5","fa-google-plus-square":"\uf0d4","fa-google-wallet":"\uf1ee","fa-graduation-cap":"\uf19d","fa-gratipay":"\uf184","fa-group":"\uf0c0","fa-h-square":"\uf0fd","fa-hacker-news":"\uf1d4","fa-hand-grab-o":"\uf255","fa-hand-lizard-o":"\uf258","fa-hand-o-down":"\uf0a7","fa-hand-o-left":"\uf0a5","fa-hand-o-right":"\uf0a4","fa-hand-o-up":"\uf0a6","fa-hand-paper-o":"\uf256","fa-hand-peace-o":"\uf25b","fa-hand-pointer-o":"\uf25a","fa-hand-rock-o":"\uf255","fa-hand-scissors-o":"\uf257","fa-hand-spock-o":"\uf259","fa-hand-stop-o":"\uf256","fa-hdd-o":"\uf0a0","fa-header":"\uf1dc","fa-headphones":"\uf025","fa-heart":"\uf004","fa-heart-o":"\uf08a","fa-heartbeat":"\uf21e","fa-history":"\uf1da","fa-home":"\uf015","fa-hospital-o":"\uf0f8","fa-hotel":"\uf236","fa-hourglass":"\uf254","fa-hourglass-1":"\uf251","fa-hourglass-2":"\uf252","fa-hourglass-3":"\uf253","fa-hourglass-end":"\uf253","fa-hourglass-half":"\uf252","fa-hourglass-o":"\uf250","fa-hourglass-start":"\uf251","fa-houzz":"\uf27c","fa-html5":"\uf13b","fa-i-cursor":"\uf246","fa-ils":"\uf20b","fa-image":"\uf03e","fa-inbox":"\uf01c","fa-indent":"\uf03c","fa-industry":"\uf275","fa-info":"\uf129","fa-info-circle":"\uf05a","fa-inr":"\uf156","fa-instagram":"\uf16d","fa-institution":"\uf19c","fa-internet-explorer":"\uf26b","fa-intersex":"\uf224","fa-ioxhost":"\uf208","fa-italic":"\uf033","fa-joomla":"\uf1aa","fa-jpy":"\uf157","fa-jsfiddle":"\uf1cc","fa-key":"\uf084","fa-keyboard-o":"\uf11c","fa-krw":"\uf159","fa-language":"\uf1ab","fa-laptop":"\uf109","fa-lastfm":"\uf202","fa-lastfm-square":"\uf203","fa-leaf":"\uf06c","fa-leanpub":"\uf212","fa-legal":"\uf0e3","fa-lemon-o":"\uf094","fa-level-down":"\uf149","fa-level-up":"\uf148","fa-life-bouy":"\uf1cd","fa-life-buoy":"\uf1cd","fa-life-ring":"\uf1cd","fa-life-saver":"\uf1cd","fa-lightbulb-o":"\uf0eb","fa-line-chart":"\uf201","fa-link":"\uf0c1","fa-linkedin":"\uf0e1","fa-linkedin-square":"\uf08c","fa-linux":"\uf17c","fa-list":"\uf03a","fa-list-alt":"\uf022","fa-list-ol":"\uf0cb","fa-list-ul":"\uf0ca","fa-location-arrow":"\uf124","fa-lock":"\uf023","fa-long-arrow-down":"\uf175","fa-long-arrow-alt-down":"\uf309","fa-long-arrow-left":"\uf177","fa-long-arrow-alt-left":"\uf30a","fa-long-arrow-right":"\uf178","fa-long-arrow-alt-right":"\uf30b","fa-long-arrow-up":"\uf176","fa-long-arrow-alt-up":"\uf30c","fa-magic":"\uf0d0","fa-magnet":"\uf076","fa-mail-forward":"\uf064","fa-mail-reply":"\uf112","fa-mail-reply-all":"\uf122","fa-male":"\uf183","fa-map":"\uf279","fa-map-marker":"\uf041","fa-map-o":"\uf278","fa-map-pin":"\uf276","fa-map-signs":"\uf277","fa-mars":"\uf222","fa-mars-double":"\uf227","fa-mars-stroke":"\uf229","fa-mars-stroke-h":"\uf22b","fa-mars-stroke-v":"\uf22a","fa-maxcdn":"\uf136","fa-meanpath":"\uf20c","fa-medium":"\uf23a","fa-medkit":"\uf0fa","fa-meh-o":"\uf11a","fa-mercury":"\uf223","fa-microphone":"\uf130","fa-microphone-slash":"\uf131","fa-minus":"\uf068","fa-minus-circle":"\uf056","fa-minus-square":"\uf146","fa-minus-square-o":"\uf147","fa-mobile":"\uf10b","fa-mobile-phone":"\uf10b","fa-money":"\uf0d6","fa-moon-o":"\uf186","fa-mortar-board":"\uf19d","fa-motorcycle":"\uf21c","fa-mouse-pointer":"\uf245","fa-music":"\uf001","fa-navicon":"\uf0c9","fa-neuter":"\uf22c","fa-newspaper-o":"\uf1ea","fa-object-group":"\uf247","fa-object-ungroup":"\uf248","fa-odnoklassniki":"\uf263","fa-odnoklassniki-square":"\uf264","fa-opencart":"\uf23d","fa-openid":"\uf19b","fa-opera":"\uf26a","fa-optin-monster":"\uf23c","fa-outdent":"\uf03b","fa-pagelines":"\uf18c","fa-paint-brush":"\uf1fc","fa-paper-plane":"\uf1d8","fa-paper-plane-o":"\uf1d9","fa-paperclip":"\uf0c6","fa-paragraph":"\uf1dd","fa-paste":"\uf0ea","fa-pause":"\uf04c","fa-paw":"\uf1b0","fa-paypal":"\uf1ed","fa-pencil":"\uf040","fa-pencil-square":"\uf14b","fa-pencil-square-o":"\uf044","fa-phone":"\uf095","fa-phone-square":"\uf098","fa-photo":"\uf03e","fa-picture-o":"\uf03e","fa-pie-chart":"\uf200","fa-pied-piper":"\uf1a7","fa-pied-piper-alt":"\uf1a8","fa-pinterest":"\uf0d2","fa-pinterest-p":"\uf231","fa-pinterest-square":"\uf0d3","fa-plane":"\uf072","fa-play":"\uf04b","fa-play-circle":"\uf144","fa-play-circle-o":"\uf01d","fa-plug":"\uf1e6","fa-plus":"\uf067","fa-plus-circle":"\uf055","fa-plus-square":"\uf0fe","fa-plus-square-o":"\uf196","fa-power-off":"\uf011","fa-print":"\uf02f","fa-puzzle-piece":"\uf12e","fa-qq":"\uf1d6","fa-qrcode":"\uf029","fa-question":"\uf128","fa-question-circle":"\uf059","fa-quote-left":"\uf10d","fa-quote-right":"\uf10e","fa-ra":"\uf1d0","fa-random":"\uf074","fa-rebel":"\uf1d0","fa-recycle":"\uf1b8","fa-reddit":"\uf1a1","fa-reddit-square":"\uf1a2","fa-refresh":"\uf021","fa-registered":"\uf25d","fa-remove":"\uf00d","fa-renren":"\uf18b","fa-reorder":"\uf0c9","fa-repeat":"\uf01e","fa-reply":"\uf112","fa-reply-all":"\uf122","fa-retweet":"\uf079","fa-rmb":"\uf157","fa-road":"\uf018","fa-rocket":"\uf135","fa-rotate-left":"\uf0e2","fa-rotate-right":"\uf01e","fa-rouble":"\uf158","fa-rss":"\uf09e","fa-rss-square":"\uf143","fa-rub":"\uf158","fa-ruble":"\uf158","fa-rupee":"\uf156","fa-safari":"\uf267","fa-save":"\uf0c7","fa-scissors":"\uf0c4","fa-search":"\uf002","fa-search-minus":"\uf010","fa-search-plus":"\uf00e","fa-sellsy":"\uf213","fa-send":"\uf1d8","fa-send-o":"\uf1d9","fa-server":"\uf233","fa-share":"\uf064","fa-share-alt":"\uf1e0","fa-share-alt-square":"\uf1e1","fa-share-square":"\uf14d","fa-share-square-o":"\uf045","fa-shekel":"\uf20b","fa-sheqel":"\uf20b","fa-shield":"\uf132","fa-ship":"\uf21a","fa-shirtsinbulk":"\uf214","fa-shopping-cart":"\uf07a","fa-sign-in":"\uf090","fa-sign-out":"\uf08b","fa-signal":"\uf012","fa-simplybuilt":"\uf215","fa-sitemap":"\uf0e8","fa-skyatlas":"\uf216","fa-skype":"\uf17e","fa-slack":"\uf198","fa-sliders":"\uf1de","fa-slideshare":"\uf1e7","fa-smile-o":"\uf118","fa-soccer-ball-o":"\uf1e3","fa-sort":"\uf0dc","fa-sort-alpha-asc":"\uf15d","fa-sort-alpha-desc":"\uf15e","fa-sort-amount-asc":"\uf160","fa-sort-amount-desc":"\uf161","fa-sort-asc":"\uf0de","fa-sort-desc":"\uf0dd","fa-sort-down":"\uf0dd","fa-sort-numeric-asc":"\uf162","fa-sort-numeric-desc":"\uf163","fa-sort-up":"\uf0de","fa-soundcloud":"\uf1be","fa-space-shuttle":"\uf197","fa-spinner":"\uf110","fa-spoon":"\uf1b1","fa-spotify":"\uf1bc","fa-square":"\uf0c8","fa-square-o":"\uf096","fa-stack-exchange":"\uf18d","fa-stack-overflow":"\uf16c","fa-star":"\uf005","fa-star-half":"\uf089","fa-star-half-empty":"\uf123","fa-star-half-full":"\uf123","fa-star-half-o":"\uf123","fa-star-o":"\uf006","fa-steam":"\uf1b6","fa-steam-square":"\uf1b7","fa-step-backward":"\uf048","fa-step-forward":"\uf051","fa-stethoscope":"\uf0f1","fa-sticky-note":"\uf249","fa-sticky-note-o":"\uf24a","fa-stop":"\uf04d","fa-street-view":"\uf21d","fa-strikethrough":"\uf0cc","fa-stumbleupon":"\uf1a4","fa-stumbleupon-circle":"\uf1a3","fa-subscript":"\uf12c","fa-subway":"\uf239","fa-suitcase":"\uf0f2","fa-sun-o":"\uf185","fa-superscript":"\uf12b","fa-support":"\uf1cd","fa-table":"\uf0ce","fa-tablet":"\uf10a","fa-tachometer":"\uf0e4","fa-tag":"\uf02b","fa-tags":"\uf02c","fa-tasks":"\uf0ae","fa-taxi":"\uf1ba","fa-television":"\uf26c","fa-tencent-weibo":"\uf1d5","fa-terminal":"\uf120","fa-text-height":"\uf034","fa-text-width":"\uf035","fa-th":"\uf00a","fa-th-large":"\uf009","fa-th-list":"\uf00b","fa-thumb-tack":"\uf08d","fa-thumbs-down":"\uf165","fa-thumbs-o-down":"\uf088","fa-thumbs-o-up":"\uf087","fa-thumbs-up":"\uf164","fa-ticket":"\uf145","fa-times":"\uf00d","fa-times-circle":"\uf057","fa-times-circle-o":"\uf05c","fa-tint":"\uf043","fa-toggle-down":"\uf150","fa-toggle-left":"\uf191","fa-toggle-off":"\uf204","fa-toggle-on":"\uf205","fa-toggle-right":"\uf152","fa-toggle-up":"\uf151","fa-trademark":"\uf25c","fa-train":"\uf238","fa-transgender":"\uf224","fa-transgender-alt":"\uf225","fa-trash":"\uf1f8","fa-trash-o":"\uf014","fa-tree":"\uf1bb","fa-trello":"\uf181","fa-tripadvisor":"\uf262","fa-trophy":"\uf091","fa-truck":"\uf0d1","fa-try":"\uf195","fa-tty":"\uf1e4","fa-tumblr":"\uf173","fa-tumblr-square":"\uf174","fa-turkish-lira":"\uf195","fa-tv":"\uf26c","fa-twitch":"\uf1e8","fa-twitter":"\uf099","fa-twitter-square":"\uf081","fa-umbrella":"\uf0e9","fa-underline":"\uf0cd","fa-undo":"\uf0e2","fa-university":"\uf19c","fa-unlink":"\uf127","fa-unlock":"\uf09c","fa-unlock-alt":"\uf13e","fa-unsorted":"\uf0dc","fa-upload":"\uf093","fa-usd":"\uf155","fa-user":"\uf007","fa-user-md":"\uf0f0","fa-user-plus":"\uf234","fa-user-secret":"\uf21b","fa-user-times":"\uf235","fa-users":"\uf0c0","fa-venus":"\uf221","fa-venus-double":"\uf226","fa-venus-mars":"\uf228","fa-viacoin":"\uf237","fa-video-camera":"\uf03d","fa-vimeo":"\uf27d","fa-vimeo-square":"\uf194","fa-vine":"\uf1ca","fa-vk":"\uf189","fa-volume-down":"\uf027","fa-volume-off":"\uf026","fa-volume-up":"\uf028","fa-warning":"\uf071","fa-wechat":"\uf1d7","fa-weibo":"\uf18a","fa-weixin":"\uf1d7","fa-whatsapp":"\uf232","fa-wheelchair":"\uf193","fa-wifi":"\uf1eb","fa-wikipedia-w":"\uf266","fa-windows":"\uf17a","fa-won":"\uf159","fa-wordpress":"\uf19a","fa-wrench":"\uf0ad","fa-xing":"\uf168","fa-xing-square":"\uf169","fa-y-combinator":"\uf23b","fa-y-combinator-square":"\uf1d4","fa-yahoo":"\uf19e","fa-yc":"\uf23b","fa-yc-square":"\uf1d4","fa-yelp":"\uf1e9","fa-yen":"\uf157","fa-youtube":"\uf167","fa-youtube-play":"\uf16a","fa-youtube-square":"\uf166"}; var FONT_OPENAUTOMATION = {"oa-weather_winter":"\ue600","oa-weather_wind_speed":"\ue601","oa-weather_wind_directions_w":"\ue602","oa-weather_wind_directions_sw":"\ue603","oa-weather_wind_directions_se":"\ue604","oa-weather_wind_directions_s":"\ue605","oa-weather_wind_directions_nw":"\ue606","oa-weather_wind_directions_ne":"\ue607","oa-weather_wind_directions_n":"\ue608","oa-weather_wind_directions_e":"\ue609","oa-weather_wind":"\ue60a","oa-weather_thunderstorm":"\ue60b","oa-weather_sunset":"\ue60c","oa-weather_sunrise":"\ue60d","oa-weather_sun":"\ue60e","oa-weather_summer":"\ue60f","oa-weather_storm":"\ue610","oa-weather_station_quadra":"\ue611","oa-weather_station":"\ue612","oa-weather_snow_light":"\ue613","oa-weather_snow_heavy":"\ue614","oa-weather_snow":"\ue615","oa-weather_rain_meter":"\ue616","oa-weather_rain_light":"\ue617","oa-weather_rain_heavy":"\ue618","oa-weather_rain_gauge":"\ue619","oa-weather_rain":"\ue61a","oa-weather_pollen":"\ue61b","oa-weather_moonset":"\ue61c","oa-weather_moonrise":"\ue61d","oa-weather_moon_phases_8":"\ue61e","oa-weather_moon_phases_7_half":"\ue61f","oa-weather_moon_phases_6":"\ue620","oa-weather_moon_phases_5_full":"\ue621","oa-weather_moon_phases_4":"\ue622","oa-weather_moon_phases_3_half":"\ue623","oa-weather_moon_phases_2":"\ue624","oa-weather_moon_phases_1_new":"\ue625","oa-weather_light_meter":"\ue626","oa-weather_humidity":"\ue627","oa-weather_frost":"\ue628","oa-weather_directions":"\ue629","oa-weather_cloudy_light":"\ue62a","oa-weather_cloudy_heavy":"\ue62b","oa-weather_cloudy":"\ue62c","oa-weather_barometric_pressure":"\ue62d","oa-weather_baraometric_pressure":"\ue62e","oa-vent_ventilation_level_manual_m":"\ue62f","oa-vent_ventilation_level_automatic":"\ue630","oa-vent_ventilation_level_3":"\ue631","oa-vent_ventilation_level_2":"\ue632","oa-vent_ventilation_level_1":"\ue633","oa-vent_ventilation_level_0":"\ue634","oa-vent_ventilation_control":"\ue635","oa-vent_ventilation":"\ue636","oa-vent_used_air":"\ue637","oa-vent_supply_air":"\ue638","oa-vent_exhaust_air":"\ue639","oa-vent_bypass":"\ue63a","oa-vent_ambient_air":"\ue63b","oa-user_ext_away":"\ue63c","oa-user_away":"\ue63d","oa-user_available":"\ue63e","oa-time_timer":"\ue63f","oa-time_statistic":"\ue640","oa-time_note":"\ue641","oa-time_manual_mode":"\ue642","oa-time_graph":"\ue643","oa-time_eco_mode":"\ue644","oa-time_clock":"\ue645","oa-time_calendar":"\ue646","oa-time_automatic":"\ue647","oa-text_min":"\ue648","oa-text_max":"\ue649","oa-temp_windchill":"\ue64a","oa-temp_temperature_min":"\ue64b","oa-temp_temperature_max":"\ue64c","oa-temp_temperature":"\ue64d","oa-temp_outside":"\ue64e","oa-temp_inside":"\ue64f","oa-temp_frost":"\ue650","oa-temp_control":"\ue651","oa-status_standby":"\ue652","oa-status_open":"\ue653","oa-status_night":"\ue654","oa-status_locked":"\ue655","oa-status_frost":"\ue656","oa-status_comfort":"\ue657","oa-status_away_2":"\ue658","oa-status_away_1":"\ue659","oa-status_available":"\ue65a","oa-status_automatic":"\ue65b","oa-secur_smoke_detector":"\ue65c","oa-secur_open":"\ue65d","oa-secur_locked":"\ue65e","oa-secur_heat_protection":"\ue65f","oa-secur_frost_protection":"\ue660","oa-secur_encoding":"\ue661","oa-secur_alarm":"\ue662","oa-scene_x-mas":"\ue663","oa-scene_workshop":"\ue664","oa-scene_wine_cellar":"\ue665","oa-scene_washing_machine":"\ue666","oa-scene_visit_guests":"\ue667","oa-scene_toilet_alternat":"\ue668","oa-scene_toilet":"\ue669","oa-scene_terrace":"\ue66a","oa-scene_swimming":"\ue66b","oa-scene_summerhouse":"\ue66c","oa-scene_stove":"\ue66d","oa-scene_storeroom":"\ue66e","oa-scene_stairs":"\ue66f","oa-scene_sleeping_alternat":"\ue670","oa-scene_sleeping":"\ue671","oa-scene_shower":"\ue672","oa-scene_scene":"\ue673","oa-scene_sauna":"\ue674","oa-scene_robo_lawnmower":"\ue675","oa-scene_pool":"\ue676","oa-scene_party":"\ue677","oa-scene_office":"\ue678","oa-scene_night":"\ue679","oa-scene_microwave_oven":"\ue67a","oa-scene_making_love_clean":"\ue67b","oa-scene_making_love":"\ue67c","oa-scene_livingroom":"\ue67d","oa-scene_laundry_room_fem":"\ue67e","oa-scene_laundry_room":"\ue67f","oa-scene_keyboard":"\ue680","oa-scene_hall":"\ue681","oa-scene_garden":"\ue682","oa-scene_gaming":"\ue683","oa-scene_fitness":"\ue684","oa-scene_dressing_room":"\ue685","oa-scene_dishwasher":"\ue686","oa-scene_dinner":"\ue687","oa-scene_day":"\ue688","oa-scene_cubby":"\ue689","oa-scene_cooking":"\ue68a","oa-scene_cockle_stove":"\ue68b","oa-scene_clothes_dryer":"\ue68c","oa-scene_cleaning":"\ue68d","oa-scene_cinema":"\ue68e","oa-scene_childs_room":"\ue68f","oa-scene_bathroom":"\ue690","oa-scene_bath":"\ue691","oa-scene_baking_oven":"\ue692","oa-scene_baby":"\ue693","oa-sani_water_tap":"\ue694","oa-sani_water_hot":"\ue695","oa-sani_water_cold":"\ue696","oa-sani_supply_temp":"\ue697","oa-sani_sprinkling":"\ue698","oa-sani_solar_temp":"\ue699","oa-sani_solar":"\ue69a","oa-sani_return_temp":"\ue69b","oa-sani_pump":"\ue69c","oa-sani_irrigation":"\ue69d","oa-sani_heating_temp":"\ue69e","oa-sani_heating_manual":"\ue69f","oa-sani_heating_automatic":"\ue6a0","oa-sani_heating":"\ue6a1","oa-sani_garden_pump":"\ue6a2","oa-sani_floor_heating":"\ue6a3","oa-sani_earth_source_heat_pump":"\ue6a4","oa-sani_domestic_waterworks":"\ue6a5","oa-sani_buffer_temp_up":"\ue6a6","oa-sani_buffer_temp_down":"\ue6a7","oa-sani_buffer_temp_all":"\ue6a8","oa-sani_boiler_temp":"\ue6a9","oa-phone_ring_out":"\ue6aa","oa-phone_ring_in":"\ue6ab","oa-phone_ring":"\ue6ac","oa-phone_missed_out":"\ue6ad","oa-phone_missed_in":"\ue6ae","oa-phone_dial":"\ue6af","oa-phone_call_out":"\ue6b0","oa-phone_call_in":"\ue6b1","oa-phone_call_end_out":"\ue6b2","oa-phone_call_end_in":"\ue6b3","oa-phone_call_end":"\ue6b4","oa-phone_call":"\ue6b5","oa-phone_answersing":"\ue6b6","oa-message_tendency_upward":"\ue6b7","oa-message_tendency_steady":"\ue6b8","oa-message_tendency_downward":"\ue6b9","oa-message_socket_on_off":"\ue6ba","oa-message_socket_ch_3":"\ue6bb","oa-message_socket_ch":"\ue6bc","oa-message_socket":"\ue6bd","oa-message_service":"\ue6be","oa-message_presence_disabled":"\ue6bf","oa-message_presence":"\ue6c0","oa-message_ok":"\ue6c1","oa-message_medicine":"\ue6c2","oa-message_mail_open":"\ue6c3","oa-message_mail":"\ue6c4","oa-message_light_intensity":"\ue6c5","oa-message_garbage":"\ue6c6","oa-message_attention":"\ue6c7","oa-measure_water_meter":"\ue6c8","oa-measure_voltage":"\ue6c9","oa-measure_power_meter":"\ue6ca","oa-measure_power":"\ue6cb","oa-measure_photovoltaic_inst":"\ue6cc","oa-measure_current":"\ue6cd","oa-measure_battery_100":"\ue6ce","oa-measure_battery_75":"\ue6cf","oa-measure_battery_50":"\ue6d0","oa-measure_battery_25":"\ue6d1","oa-measure_battery_0":"\ue6d2","oa-light_wire_system_2":"\ue6d3","oa-light_wire_system_1":"\ue6d4","oa-light_wall_3":"\ue6d5","oa-light_wall_2":"\ue6d6","oa-light_wall_1":"\ue6d7","oa-light_uplight":"\ue6d8","oa-light_stairs":"\ue6d9","oa-light_pendant_light_round":"\ue6da","oa-light_pendant_light":"\ue6db","oa-light_party":"\ue6dc","oa-light_outdoor":"\ue6dd","oa-light_office_desk":"\ue6de","oa-light_office":"\ue6df","oa-light_mirror":"\ue6e0","oa-light_light_dim_100":"\ue6e1","oa-light_light_dim_90":"\ue6e2","oa-light_light_dim_80":"\ue6e3","oa-light_light_dim_70":"\ue6e4","oa-light_light_dim_60":"\ue6e5","oa-light_light_dim_50":"\ue6e6","oa-light_light_dim_40":"\ue6e7","oa-light_light_dim_30":"\ue6e8","oa-light_light_dim_20":"\ue6e9","oa-light_light_dim_10":"\ue6ea","oa-light_light_dim_00":"\ue6eb","oa-light_light":"\ue6ec","oa-light_led_stripe_rgb":"\ue6ed","oa-light_led_stripe":"\ue6ee","oa-light_led":"\ue6ef","oa-light_floor_lamp":"\ue6f0","oa-light_fairy_lights":"\ue6f1","oa-light_downlight":"\ue6f2","oa-light_dinner_table":"\ue6f3","oa-light_diffused":"\ue6f4","oa-light_control":"\ue6f5","oa-light_ceiling_light":"\ue6f6","oa-light_cabinet":"\ue6f7","oa-it_wireless_dcf77":"\ue6f8","oa-it_wifi":"\ue6f9","oa-it_television":"\ue6fa","oa-it_telephone":"\ue6fb","oa-it_smartphone":"\ue6fc","oa-it_server":"\ue6fd","oa-it_satellite_dish_heating":"\ue6fe","oa-it_satellite_dish":"\ue6ff","oa-it_router":"\ue700","oa-it_remote":"\ue701","oa-it_radio":"\ue702","oa-it_pc":"\ue703","oa-it_network":"\ue704","oa-it_net":"\ue705","oa-it_nas":"\ue706","oa-it_internet":"\ue707","oa-it_fax":"\ue708","oa-it_camera":"\ue709","oa-fts_window_roof_shutter":"\ue70a","oa-fts_window_roof_open_2":"\ue70b","oa-fts_window_roof_open_1":"\ue70c","oa-fts_window_roof":"\ue70d","oa-fts_window_louvre_open":"\ue70e","oa-fts_window_louvre":"\ue70f","oa-fts_window_2w_tilt_r":"\ue710","oa-fts_window_2w_tilt_lr":"\ue711","oa-fts_window_2w_tilt_l_open_r":"\ue712","oa-fts_window_2w_tilt_l":"\ue713","oa-fts_window_2w_tilt":"\ue714","oa-fts_window_2w_open_r":"\ue715","oa-fts_window_2w_open_lr":"\ue716","oa-fts_window_2w_open_l_tilt_r":"\ue717","oa-fts_window_2w_open_l":"\ue718","oa-fts_window_2w_open":"\ue719","oa-fts_window_2w":"\ue71a","oa-fts_window_1w_tilt":"\ue71b","oa-fts_window_1w_open":"\ue71c","oa-fts_window_1w":"\ue71d","oa-fts_sunblind":"\ue71e","oa-fts_sliding_gate":"\ue71f","oa-fts_shutter_up":"\ue720","oa-fts_shutter_manual":"\ue721","oa-fts_shutter_down":"\ue722","oa-fts_shutter_automatic":"\ue723","oa-fts_shutter_100":"\ue724","oa-fts_shutter_90":"\ue725","oa-fts_shutter_80":"\ue726","oa-fts_shutter_70":"\ue727","oa-fts_shutter_60":"\ue728","oa-fts_shutter_50":"\ue729","oa-fts_shutter_40":"\ue72a","oa-fts_shutter_30":"\ue72b","oa-fts_shutter_20":"\ue72c","oa-fts_shutter_10":"\ue72d","oa-fts_shutter":"\ue72e","oa-fts_light_dome_open":"\ue72f","oa-fts_light_dome":"\ue730","oa-fts_garage_door_100":"\ue731","oa-fts_garage_door_90":"\ue732","oa-fts_garage_door_80":"\ue733","oa-fts_garage_door_70":"\ue734","oa-fts_garage_door_60":"\ue735","oa-fts_garage_door_50":"\ue736","oa-fts_garage_door_40":"\ue737","oa-fts_garage_door_30":"\ue738","oa-fts_garage_door_20":"\ue739","oa-fts_garage_door_10":"\ue73a","oa-fts_garage":"\ue73b","oa-fts_door_slide_open_m":"\ue73c","oa-fts_door_slide_open":"\ue73d","oa-fts_door_slide_m":"\ue73e","oa-fts_door_slide_2w_open_r":"\ue73f","oa-fts_door_slide_2w_open_lr":"\ue740","oa-fts_door_slide_2w_open_l":"\ue741","oa-fts_door_slide_2w":"\ue742","oa-fts_door_slide":"\ue743","oa-fts_door_open":"\ue744","oa-fts_door":"\ue745","oa-fts_blade_z_sun":"\ue746","oa-fts_blade_z":"\ue747","oa-fts_blade_s_sun":"\ue748","oa-fts_blade_s":"\ue749","oa-fts_blade_arc_sun":"\ue74a","oa-fts_blade_arc_close_100":"\ue74b","oa-fts_blade_arc_close_50":"\ue74c","oa-fts_blade_arc_close_00":"\ue74d","oa-fts_blade_arc":"\ue74e","oa-edit_sort":"\ue74f","oa-edit_settings":"\ue750","oa-edit_save":"\ue751","oa-edit_paste":"\ue752","oa-edit_open":"\ue753","oa-edit_expand":"\ue754","oa-edit_delete":"\ue755","oa-edit_cut":"\ue756","oa-edit_copy":"\ue757","oa-edit_collapse":"\ue758","oa-control_zoom_out":"\ue759","oa-control_zoom_in":"\ue75a","oa-control_x":"\ue75b","oa-control_standby":"\ue75c","oa-control_return":"\ue75d","oa-control_reboot":"\ue75e","oa-control_plus":"\ue75f","oa-control_outside_on_off":"\ue760","oa-control_on_off":"\ue761","oa-control_minus":"\ue762","oa-control_home":"\ue763","oa-control_centr_arrow_up_right":"\ue764","oa-control_centr_arrow_up_left":"\ue765","oa-control_centr_arrow_up":"\ue766","oa-control_centr_arrow_right":"\ue767","oa-control_centr_arrow_left":"\ue768","oa-control_centr_arrow_down_right":"\ue769","oa-control_centr_arrow_down_left":"\ue76a","oa-control_centr_arrow_down":"\ue76b","oa-control_building_s_og":"\ue76c","oa-control_building_s_kg":"\ue76d","oa-control_building_s_eg":"\ue76e","oa-control_building_s_dg":"\ue76f","oa-control_building_s_all":"\ue770","oa-control_building_outside":"\ue771","oa-control_building_og":"\ue772","oa-control_building_modern_s_okg_og":"\ue773","oa-control_building_modern_s_okg_eg":"\ue774","oa-control_building_modern_s_okg_dg":"\ue775","oa-control_building_modern_s_okg_all":"\ue776","oa-control_building_modern_s_og":"\ue777","oa-control_building_modern_s_kg":"\ue778","oa-control_building_modern_s_eg":"\ue779","oa-control_building_modern_s_dg":"\ue77a","oa-control_building_modern_s_all":"\ue77b","oa-control_building_modern_s_2og_og2":"\ue77c","oa-control_building_modern_s_2og_og1":"\ue77d","oa-control_building_modern_s_2og_kg":"\ue77e","oa-control_building_modern_s_2og_eg":"\ue77f","oa-control_building_modern_s_2og_dg":"\ue780","oa-control_building_modern_s_2og_all":"\ue781","oa-control_building_kg":"\ue782","oa-control_building_filled":"\ue783","oa-control_building_empty":"\ue784","oa-control_building_eg":"\ue785","oa-control_building_dg":"\ue786","oa-control_building_control":"\ue787","oa-control_building_all":"\ue788","oa-control_building_2_s_kg":"\ue789","oa-control_building_2_s_eg":"\ue78a","oa-control_building_2_s_dg":"\ue78b","oa-control_building_2_s_all":"\ue78c","oa-control_arrow_upward":"\ue78d","oa-control_arrow_up_right":"\ue78e","oa-control_arrow_up_left":"\ue78f","oa-control_arrow_up":"\ue790","oa-control_arrow_turn_right":"\ue791","oa-control_arrow_turn_left":"\ue792","oa-control_arrow_rightward":"\ue793","oa-control_arrow_right":"\ue794","oa-control_arrow_leftward":"\ue795","oa-control_arrow_left":"\ue796","oa-control_arrow_downward":"\ue797","oa-control_arrow_down_right":"\ue798","oa-control_arrow_down_left":"\ue799","oa-control_arrow_down":"\ue79a","oa-control_all_on_off":"\ue79b","oa-control_4":"\ue79c","oa-control_3":"\ue79d","oa-control_2":"\ue79e","oa-control_1":"\ue79f","oa-audio_volume_mute":"\ue7a0","oa-audio_volume_mid":"\ue7a1","oa-audio_volume_low":"\ue7a2","oa-audio_volume_high":"\ue7a3","oa-audio_stop":"\ue7a4","oa-audio_sound":"\ue7a5","oa-audio_shuffle":"\ue7a6","oa-audio_rew":"\ue7a7","oa-audio_repeat":"\ue7a8","oa-audio_rec":"\ue7a9","oa-audio_playlist":"\ue7aa","oa-audio_play":"\ue7ab","oa-audio_pause":"\ue7ac","oa-audio_mic_mute":"\ue7ad","oa-audio_mic":"\ue7ae","oa-audio_loudness":"\ue7af","oa-audio_headphone":"\ue7b0","oa-audio_ff":"\ue7b1","oa-audio_fade":"\ue7b2","oa-audio_eq":"\ue7b3","oa-audio_eject":"\ue7b4","oa-audio_audio":"\ue7b5"}; var FONT_FHEMSVG = {"fs-user_unknown":"\ue600","fs-usb_stick":"\ue601","fs-usb":"\ue602","fs-unlock":"\ue603","fs-unknown":"\ue604","fs-temperature_humidity":"\ue605","fs-taster_ch6_6":"\ue606","fs-taster_ch6_5":"\ue607","fs-taster_ch6_4":"\ue608","fs-taster_ch6_3":"\ue609","fs-taster_ch6_2":"\ue60a","fs-taster_ch6_1":"\ue60b","fs-taster_ch_aus_rot .path1":"\ue60c","fs-taster_ch_aus_rot .path2":"\ue60d","fs-taster_ch_aus_rot .path3":"\ue60e","fs-taster_ch_aus_rot .path4":"\ue60f","fs-taster_ch_aus_rot .path5":"\ue610","fs-taster_ch_aus_rot .path6":"\ue611","fs-taster_ch_an_gruen .path1":"\ue612","fs-taster_ch_an_gruen .path2":"\ue613","fs-taster_ch_an_gruen .path3":"\ue614","fs-taster_ch_an_gruen .path4":"\ue615","fs-taster_ch_an_gruen .path5":"\ue616","fs-taster_ch_2":"\ue617","fs-taster_ch_1":"\ue618","fs-taster_ch":"\ue619","fs-taster":"\ue61a","fs-system_fhem_update":"\ue61b","fs-system_fhem_reboot":"\ue61c","fs-system_fhem":"\ue61d","fs-system_backup":"\ue61e","fs-socket_timer":"\ue61f","fs-security_password":"\ue620","fs-security":"\ue621","fs-sdcard":"\ue622","fs-scc_868":"\ue623","fs-sani_heating_timer":"\ue624","fs-sani_heating_level_100":"\ue625","fs-sani_heating_level_90":"\ue626","fs-sani_heating_level_80":"\ue627","fs-sani_heating_level_70":"\ue628","fs-sani_heating_level_60":"\ue629","fs-sani_heating_level_50":"\ue62a","fs-sani_heating_level_40":"\ue62b","fs-sani_heating_level_30":"\ue62c","fs-sani_heating_level_20":"\ue62d","fs-sani_heating_level_10":"\ue62e","fs-sani_heating_level_0":"\ue62f","fs-sani_heating_calendar":"\ue630","fs-sani_heating_boost":"\ue631","fs-sani_floor_heating_off":"\ue632","fs-sani_floor_heating_neutral":"\ue633","fs-RPi .path1":"\ue634","fs-RPi .path2":"\ue635","fs-RPi .path3":"\ue636","fs-RPi .path4":"\ue637","fs-RPi .path5":"\ue638","fs-RPi .path6":"\ue639","fs-RPi .path7":"\ue63a","fs-RPi .path8":"\ue63b","fs-RPi .path9":"\ue63c","fs-RPi .path10":"\ue63d","fs-RPi .path11":"\ue63e","fs-RPi .path12":"\ue63f","fs-RPi .path13":"\ue640","fs-RPi .path14":"\ue641","fs-RPi .path15":"\ue642","fs-RPi .path16":"\ue643","fs-RPi .path17":"\ue644","fs-RPi .path18":"\ue645","fs-RPi .path19":"\ue646","fs-RPi .path20":"\ue647","fs-RPi .path21":"\ue648","fs-remote_control":"\ue649","fs-refresh":"\ue64a","fs-recycling":"\ue64b","fs-rc_YELLOW .path1":"\ue64c","fs-rc_YELLOW .path2":"\ue64d","fs-rc_WEB":"\ue64e","fs-rc_VOLUP":"\ue64f","fs-rc_VOLPLUS":"\ue650","fs-rc_VOLMINUS":"\ue651","fs-rc_VOLDOWN":"\ue652","fs-rc_VIDEO":"\ue653","fs-rc_USB":"\ue654","fs-rc_UP":"\ue655","fs-rc_TVstop":"\ue656","fs-rc_TV":"\ue657","fs-rc_TEXT":"\ue658","fs-rc_templatebutton":"\ue659","fs-rc_SUB":"\ue65a","fs-rc_STOP":"\ue65b","fs-rc_SHUFFLE":"\ue65c","fs-rc_SETUP":"\ue65d","fs-rc_SEARCH":"\ue65e","fs-rc_RIGHT":"\ue65f","fs-rc_REWred":"\ue660","fs-rc_REW":"\ue661","fs-rc_REPEAT":"\ue662","fs-rc_RED .path1":"\ue663","fs-rc_RED .path2":"\ue664","fs-rc_REC .path1":"\ue665","fs-rc_REC .path2":"\ue666","fs-rc_RADIOred":"\ue667","fs-rc_RADIO":"\ue668","fs-rc_PREVIOUS":"\ue669","fs-rc_POWER":"\ue66a","fs-rc_PLUS":"\ue66b","fs-rc_PLAYgreen":"\ue66c","fs-rc_PLAY":"\ue66d","fs-rc_PAUSEyellow":"\ue66e","fs-rc_PAUSE":"\ue66f","fs-rc_OPTIONS":"\ue670","fs-rc_OK":"\ue671","fs-rc_NEXT":"\ue672","fs-rc_MUTE":"\ue673","fs-rc_MINUS":"\ue674","fs-rc_MENU":"\ue675","fs-rc_MEDIAMENU":"\ue676","fs-rc_LEFT":"\ue677","fs-rc_INFO":"\ue678","fs-rc_HOME":"\ue679","fs-rc_HELP":"\ue67a","fs-rc_HDMI":"\ue67b","fs-rc_GREEN .path1":"\ue67c","fs-rc_GREEN .path2":"\ue67d","fs-rc_FFblue":"\ue67e","fs-rc_FF":"\ue67f","fs-rc_EXIT":"\ue680","fs-rc_EPG":"\ue681","fs-rc_EJECT":"\ue682","fs-rc_DOWN":"\ue683","fs-rc_dot":"\ue684","fs-rc_BLUE .path1":"\ue685","fs-rc_BLUE .path2":"\ue686","fs-rc_BLANK":"\ue687","fs-rc_BACK":"\ue688","fs-rc_AV":"\ue689","fs-rc_AUDIO":"\ue68a","fs-rc_9":"\ue68b","fs-rc_8":"\ue68c","fs-rc_7":"\ue68d","fs-rc_6":"\ue68e","fs-rc_5":"\ue68f","fs-rc_4":"\ue690","fs-rc_3":"\ue691","fs-rc_2":"\ue692","fs-rc_1":"\ue693","fs-rc_0":"\ue694","fs-people_sensor":"\ue695","fs-outside_socket":"\ue696","fs-motion_detector":"\ue697","fs-message_socket_unknown":"\ue698","fs-message_socket_on2":"\ue699","fs-message_socket_off2":"\ue69a","fs-message_socket_off":"\ue69b","fs-message_socket_enabled":"\ue69c","fs-message_socket_disabled":"\ue69d","fs-max_wandthermostat":"\ue69e","fs-max_heizungsthermostat":"\ue69f","fs-lock":"\ue6a0","fs-light_toggle":"\ue6a1","fs-light_question .path1":"\ue6a2","fs-light_question .path2":"\ue6a3","fs-light_question .path3":"\ue6a4","fs-light_question .path4":"\ue6a5","fs-light_question .path5":"\ue6a6","fs-light_question .path6":"\ue6a7","fs-light_outdoor":"\ue6a8","fs-light_on-for-timer":"\ue6a9","fs-light_off-for-timer":"\ue6aa","fs-light_exclamation .path1":"\ue6ab","fs-light_exclamation .path2":"\ue6ac","fs-light_exclamation .path3":"\ue6ad","fs-light_exclamation .path4":"\ue6ae","fs-light_exclamation .path5":"\ue6af","fs-light_exclamation .path6":"\ue6b0","fs-light_dim_up":"\ue6b1","fs-light_dim_down":"\ue6b2","fs-light_ceiling_off":"\ue6b3","fs-light_ceiling":"\ue6b4","fs-lan_rs485":"\ue6b5","fs-it_remote_folder .path1":"\ue6b6","fs-it_remote_folder .path2":"\ue6b7","fs-it_remote_folder .path3":"\ue6b8","fs-it_remote_folder .path4":"\ue6b9","fs-it_remote_folder .path5":"\ue6ba","fs-it_remote_folder .path6":"\ue6bb","fs-it_remote_folder .path7":"\ue6bc","fs-it_remote_folder .path8":"\ue6bd","fs-it_remote_folder .path9":"\ue6be","fs-it_remote_folder .path10":"\ue6bf","fs-it_remote_folder .path11":"\ue6c0","fs-it_remote_folder .path12":"\ue6c1","fs-it_remote_folder .path13":"\ue6c2","fs-it_remote_folder .path14":"\ue6c3","fs-it_remote_folder .path15":"\ue6c4","fs-it_remote_folder .path16":"\ue6c5","fs-it_remote_folder .path17":"\ue6c6","fs-it_remote_folder .path18":"\ue6c7","fs-it_remote_folder .path19":"\ue6c8","fs-it_remote_folder .path20":"\ue6c9","fs-it_remote_folder .path21":"\ue6ca","fs-it_i-net":"\ue6cb","fs-it_hue_bridge .path1":"\ue6cc","fs-it_hue_bridge .path2":"\ue6cd","fs-it_hue_bridge .path3":"\ue6ce","fs-it_hue_bridge .path4":"\ue6cf","fs-it_hue_bridge .path5":"\ue6d0","fs-it_hue_bridge .path6":"\ue6d1","fs-it_hue_bridge .path7":"\ue6d2","fs-it_hue_bridge .path8":"\ue6d3","fs-it_hue_bridge .path9":"\ue6d4","fs-it_hue_bridge .path10":"\ue6d5","fs-it_hue_bridge .path11":"\ue6d6","fs-it_hue_bridge .path12":"\ue6d7","fs-it_hue_bridge .path13":"\ue6d8","fs-it_hue_bridge .path14":"\ue6d9","fs-it_hue_bridge .path15":"\ue6da","fs-it_hue_bridge .path16":"\ue6db","fs-it_hue_bridge .path17":"\ue6dc","fs-it_hue_bridge .path18":"\ue6dd","fs-it_hue_bridge .path19":"\ue6de","fs-it_hue_bridge .path20":"\ue6df","fs-it_hue_bridge .path21":"\ue6e0","fs-it_hue_bridge .path22":"\ue6e1","fs-it_hue_bridge .path23":"\ue6e2","fs-IR":"\ue6e3","fs-Icon_Fisch":"\ue6e4","fs-humidity":"\ue6e5","fs-hue_bridge .path1":"\ue6e6","fs-hue_bridge .path2":"\ue6e7","fs-hue_bridge .path3":"\ue6e8","fs-hue_bridge .path4":"\ue6e9","fs-hue_bridge .path5":"\ue6ea","fs-hue_bridge .path6":"\ue6eb","fs-hue_bridge .path7":"\ue6ec","fs-hue_bridge .path8":"\ue6ed","fs-hue_bridge .path9":"\ue6ee","fs-hue_bridge .path10":"\ue6ef","fs-hue_bridge .path11":"\ue6f0","fs-hue_bridge .path12":"\ue6f1","fs-hue_bridge .path13":"\ue6f2","fs-hue_bridge .path14":"\ue6f3","fs-hue_bridge .path15":"\ue6f4","fs-hue_bridge .path16":"\ue6f5","fs-hue_bridge .path17":"\ue6f6","fs-hue_bridge .path18":"\ue6f7","fs-hue_bridge .path19":"\ue6f8","fs-hue_bridge .path20":"\ue6f9","fs-hue_bridge .path21":"\ue6fa","fs-hue_bridge .path22":"\ue6fb","fs-hue_bridge .path23":"\ue6fc","fs-hourglass":"\ue6fd","fs-hm-tc-it-wm-w-eu":"\ue6fe","fs-hm-dis-wm55":"\ue6ff","fs-hm-cc-rt-dn":"\ue700","fs-hm_lan":"\ue701","fs-hm_keymatic":"\ue702","fs-hm_ccu":"\ue703","fs-general_ok":"\ue704","fs-general_low":"\ue705","fs-general_aus_fuer_zeit":"\ue706","fs-general_aus":"\ue707","fs-general_an_fuer_zeit":"\ue708","fs-general_an":"\ue709","fs-garden_socket":"\ue70a","fs-fts_window_1wbb_open":"\ue70b","fs-fts_shutter_updown":"\ue70c","fs-fts_door_tilt":"\ue70d","fs-fts_door_right_open":"\ue70e","fs-fts_door_right":"\ue70f","fs-frost":"\ue710","fs-floor":"\ue711","fs-dustbin":"\ue712","fs-dreambox":"\ue713","fs-dog_silhouette":"\ue714","fs-DIN_rail_housing .path1":"\ue715","fs-DIN_rail_housing .path2":"\ue716","fs-DIN_rail_housing .path3":"\ue717","fs-DIN_rail_housing .path4":"\ue718","fs-DIN_rail_housing .path5":"\ue719","fs-DIN_rail_housing .path6":"\ue71a","fs-DIN_rail_housing .path7":"\ue71b","fs-DIN_rail_housing .path8":"\ue71c","fs-DIN_rail_housing .path9":"\ue71d","fs-DIN_rail_housing .path10":"\ue71e","fs-DIN_rail_housing .path11":"\ue71f","fs-DIN_rail_housing .path12":"\ue720","fs-DIN_rail_housing .path13":"\ue721","fs-DIN_rail_housing .path14":"\ue722","fs-DIN_rail_housing .path15":"\ue723","fs-DIN_rail_housing .path16":"\ue724","fs-DIN_rail_housing .path17":"\ue725","fs-DIN_rail_housing .path18":"\ue726","fs-DIN_rail_housing .path19":"\ue727","fs-DIN_rail_housing .path20":"\ue728","fs-DIN_rail_housing .path21":"\ue729","fs-DIN_rail_housing .path22":"\ue72a","fs-DIN_rail_housing .path23":"\ue72b","fs-DIN_rail_housing .path24":"\ue72c","fs-DIN_rail_housing .path25":"\ue72d","fs-DIN_rail_housing .path26":"\ue72e","fs-DIN_rail_housing .path27":"\ue72f","fs-DIN_rail_housing .path28":"\ue730","fs-DIN_rail_housing .path29":"\ue731","fs-DIN_rail_housing .path30":"\ue732","fs-DIN_rail_housing .path31":"\ue733","fs-DIN_rail_housing .path32":"\ue734","fs-DIN_rail_housing .path33":"\ue735","fs-DIN_rail_housing .path34":"\ue736","fs-DIN_rail_housing .path35":"\ue737","fs-DIN_rail_housing .path36":"\ue738","fs-DIN_rail_housing .path37":"\ue739","fs-DIN_rail_housing .path38":"\ue73a","fs-DIN_rail_housing .path39":"\ue73b","fs-DIN_rail_housing .path40":"\ue73c","fs-DIN_rail_housing .path41":"\ue73d","fs-DIN_rail_housing .path42":"\ue73e","fs-DIN_rail_housing .path43":"\ue73f","fs-DIN_rail_housing .path44":"\ue740","fs-DIN_rail_housing .path45":"\ue741","fs-DIN_rail_housing .path46":"\ue742","fs-DIN_rail_housing .path47":"\ue743","fs-DIN_rail_housing .path48":"\ue744","fs-DIN_rail_housing .path49":"\ue745","fs-day_night":"\ue746","fs-cul_usb":"\ue747","fs-cul_cul":"\ue748","fs-cul_868":"\ue749","fs-cul":"\ue74a","fs-christmas_tree":"\ue74b","fs-building_security":"\ue74c","fs-building_outside":"\ue74d","fs-building_carport_socket":"\ue74e","fs-building_carport_light":"\ue74f","fs-building_carport":"\ue750","fs-bluetooth":"\ue751","fs-batterie":"\ue752","fs-bag":"\ue753","fs-ampel_rot .path1":"\ue754","fs-ampel_rot .path2":"\ue755","fs-ampel_gruen .path1":"\ue756","fs-ampel_gruen .path2":"\ue757","fs-ampel_gelb .path1":"\ue758","fs-ampel_gelb .path2":"\ue759","fs-ampel_aus":"\ue75a","fs-alarm_system_password":"\ue75b","fs-access_keypad_2":"\ue75c","fs-access_keypad_1":"\ue75d"}; //helper code for retrieving glyph information for FONT_AWESOME, not needed for normal operation + /*var faCheatsLoaded = false; if (faPage === undefined) { @@ -299,11 +313,11 @@ var widget_chart = { case 'maxvalue_sec': case 'minvalue_sec': $.each(values,function(i,v){ - elem.data(val[0]+'_internal_'+i,v); // add additional data value with extension '_internal' (need to allow updates) - if (!$.isArray(v) && elem.isDeviceReading(val[0]+'_internal_'+i)) { - obj.addReading(elem, val[0]+'_internal_'+i); // trace new reading with extension '_internal_#num' + elem.data(val[0]+'#internal#'+i,v); // add additional data value with extension '#internal' (need to allow updates) + if (!$.isArray(v) && elem.isDeviceReading(val[0]+'#internal#'+i)) { + obj.addReading(elem, val[0]+'#internal#'+i); // trace new reading with extension '#internal##num' } else { // no device:reading setting, remove additional data value - elem.removeData(val[0]+'_internal_'+i); + elem.removeData(val[0]+'#internal#'+i); } }); break; @@ -314,18 +328,18 @@ var widget_chart = { var drary = v.split(':'); isValidDeviceReading = ftui.deviceStates[drary[0]]!==undefined; } - elem.data(val[0]+'_internal_'+i,v); // add additional data value with extension '_internal' (need to allow updates) - if (isValidDeviceReading && elem.isDeviceReading(val[0]+'_internal_'+i)) { - obj.addReading(elem, val[0]+'_internal_'+i); // trace new reading with extension '_internal_#num' + elem.data(val[0]+'#internal#'+i,v); // add additional data value with extension '#internal' (need to allow updates) + if (isValidDeviceReading && elem.isDeviceReading(val[0]+'#internal#'+i)) { + obj.addReading(elem, val[0]+'#internal#'+i); // trace new reading with extension '#internal##num' } else { // no device:reading setting, remove additional data value - elem.removeData(val[0]+'_internal_'+i); + elem.removeData(val[0]+'#internal#'+i); } }); break; } - } else if (val[0].search(/_internal_/) > -1) { - var index = parseInt(val[0].split('_')[val[0].split('_').length-1]); - var key = val[0].split('_')[0]; + } else if (val[0].search(/#internal#/) > -1) { + var index = parseInt(val[0].split('#')[val[0].split('#').length-1]); + var key = val[0].split('#')[0]; switch(key) { case 'style': case 'maxvalue': @@ -339,7 +353,7 @@ var widget_chart = { if ((index < values.length) && (values[index] != newval)) { values[index] = newval; elem.data(key,values); - if (data.done) widget_chart.refresh(elem,'start'); + if (data.done && data.baseDone) widget_chart.refresh(elem,'start'); } } break; @@ -354,8 +368,8 @@ var widget_chart = { var mingr = (style&&style.length&&style[0]=='fill')?Math.min(min,mingraph):mingraph; var maxgr = maxgraph; var scale = (max-min)/(maxgr-mingr); - var y1 = 0-(max-maxgr)/(max-min)*scale*100; - var y2 = 100+(mingr-min)/(max-min)*scale*100; + var y1 = (mingr===Infinity||maxgr===-Infinity)?0:0-(max-maxgr)/(max-min)*scale*100; + var y2 = (mingr===Infinity||maxgr===-Infinity)?100:100+(mingr-min)/(max-min)*scale*100; var grID = instance+'_'+(k+1); // gradient ID, assuming that there are not more than 10000 instances of chart widgets per page. var styledef, styledeftext; var newdef = ''; @@ -435,6 +449,8 @@ var widget_chart = { return {stroke:strk, dash:dashArray}; }, getBrowserCaps: function() { // helper function to find out browser capabilities + if (widget_chart.gBCaps) return widget_chart.gBCaps; + if (!window.getComputedStyle) { return false; } @@ -478,9 +494,11 @@ var widget_chart = { } } - return ({'result':result,'svg_transform_needed':svg_transform_needed,'doSVGTransformCorrection':doSVGTransformCorrection,'prefix':pref.replace('transform','')}); + widget_chart.gBCaps = {'result':result,'svg_transform_needed':svg_transform_needed,'doSVGTransformCorrection':doSVGTransformCorrection,'prefix':pref.replace('transform','')}; + + return widget_chart.gBCaps; }, - getTransformedPoint: function(data,svgbase,point) { // helper function to transform 3D point in 2D view + getTransformedPoint: function(data,svgbase,point,special) { // helper function to transform 3D point in 2D view //if (!data.DDD.Active) return point; var left = (data.getGraphLeft()); var width = data.graphWidth/100*data.basewidth; @@ -498,7 +516,7 @@ var widget_chart = { ''); var attrval = {style:data.DDD.prefix+'transform:'+data.DDD.String.Scale+'; position:absolute'}; - dummy.find('div.baseforDDD').attr(attrval); + if (!special) dummy.find('div.baseforDDD').attr(attrval); attrval = {style:data.DDD.String.Rot+'; '+data.DDD.String.Trans(point.z,0,data.DDD,data.xStrTO,data.yStrTO)+'; position:absolute'}; dummy.find('div.baseRotation').attr(attrval); attrval = {style:'; left:'+left+'px; width:'+width+'px; top:'+top+'px; height:'+height+'px; position:absolute'}; @@ -666,6 +684,7 @@ var widget_chart = { var cx = {p1:[], p2:[]}; var cy = {p1:[], p2:[]}; + var disconnected_inner, disconnected_outer; for (var i=0, leni=n-1; i0?ptype.indexOf('_proxy'):ptype.length)).split('-'); + var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; + var start = subtype.search('start')>-1?true:false; + var end = subtype.search('end')>-1?true:false; + var type = ptc[0]; - switch (ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))) { + switch (type) { case 'lines': first = true; for (i=0,l=arg.length;i0 && (arg[i-1][5] && arg[i-1][5]==true))) { + res.push(" L " + arg[i][0] + "," + arg[i][1] + " Q "); + } else { + res.push(cx.p2[i] + ", " + cy.p2[i] + ", " + arg[i+1][0] + ", " + arg[i+1][1]+ " "); + } + } } } if (!proxy) res.push("L" + arg[arg.length-1][0] + "," + (closed?min + " Z":arg[arg.length-1][1])); @@ -1027,13 +1119,27 @@ var widget_chart = { case 'quadraticSmooth': first = true; for (i=0,l=arg.length-1;i0 && (arg[i-1][5] && arg[i-1][5]==true))) { + res.push(arg[i][0] + ", " + arg[i][1] + " L "); + res.push(arg[i][0] + ", " + arg[i][1] + " T "); + res.push(((arg[i][0]+arg[i+1][0])/2) + ", " + ((arg[i][1]+arg[i+1][1])/2) + " "); + } else { + res.push(((arg[i][0]+arg[i+1][0])/2) + ", " + ((arg[i][1]+arg[i+1][1])/2) + " "); + } + } } } res.push("L" + arg[arg.length-1][0] + "," + (closed?min + " Z":arg[arg.length-1][1])); @@ -1143,6 +1249,17 @@ var widget_chart = { if ($.isArray(array)) {rVal = array[Math.min(i,array.length-1)];} else if (array !== undefined) {rVal = array;} else {rVal = defVal;} return rVal; }, + getDynamicStyle: function(style) { + var ret = ''; + if ($.isArray(style) && style[0].search(/graphbase/)>=0) { + $.each(style, function(index, value) { + if (value.search(/style/)>=0) ret = value.search(':')>=0?value.split(':')[1]:''; + }); + return ret; + } else { + return style; + } + }, getArrayLength: function(array) { var n=0; if ($.isArray(array)) { @@ -1176,6 +1293,7 @@ var widget_chart = { nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.legend)); nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.style)); nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.graphsshown)); + nGraphs = Math.max(nGraphs,widget_chart.getArrayLength(data.cursorshown)); return nGraphs; }, getDateTimeNumberString: function(date,format) { // generate Date/Time String according to format given @@ -1376,7 +1494,9 @@ var widget_chart = { case 'h': // number counts in hours if (!doRounding) { now = new Date(); - ddiff = widget_chart.dateDiff(new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0), new Date(now.getFullYear(),now.getMonth(),now.getDate(),parseFloat(dStr),0,0,0), 'd'); + var hours = parseInt(dStr); + var minutes = (parseFloat(dStr) - hours)*60; + ddiff = widget_chart.dateDiff(new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0), new Date(now.getFullYear(),now.getMonth(),now.getDate(),hours,minutes,0,0), 'd'); } else { ddiff = parseFloat(dStr)/24; if (!data.nofulldays) ddiff = parseInt(ddiff); @@ -1415,7 +1535,7 @@ var widget_chart = { } else { now = new Date(); ddiff = widget_chart.dateDiff(ds, new Date(now.getFullYear(),now.getMonth(),now.getDate(),-now.getTimezoneOffset()/60-now.stdTimezoneOffset()/60,0,0,0), 'd'); - if (!data.nofulldays) ddiff = parseInt(ddiff); + if (!data.nofulldays) ddiff = parseInt(ddiff+(ddiff<0?-0.5:0.5)); return ddiff; } }, @@ -1447,7 +1567,7 @@ var widget_chart = { } }, getFormattedText: function(txt) { // helper function to generate svg text element with html formatting possibilities - var outtext = txt; + var outtext = String(txt); outtext = outtext.replace(/\/g,''); outtext = outtext.replace(/\<\/i\>/g,''); @@ -1532,7 +1652,7 @@ var widget_chart = { data.title_object = widget_chart.getFormattedText(data.title_object); }, - roundXticks: function(round_in, x, xrange, startdate) { // helper function to support correct xtick positions (rounded time values) + roundXticks: function(round_in, x, xrange, startdate, asize) { // helper function to support correct xtick positions (rounded time values) var xret = x; var round; @@ -1566,15 +1686,19 @@ var widget_chart = { xret = parseInt(x/60/24+0.5)*60*24-xstart; // correct xret to number of minutes to closest day since start date/time break; case 'w': // rounding to weeks - var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped - xret = parseInt(x/60/24/7+0.5)*60*24*7-xstart; // correct xret to number of minutes to closest first day of week since start date/time + if (asize == 7) { + var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()*60*24; // correction needed to be sure that hours inside full day are skipped + } else if (asize == 3.5) { + var xstart = startdate.getMinutes()+startdate.getHours()*60+startdate.getDay()/2*60*24; // correction needed to be sure that hours inside full day are skipped + } + xret = parseInt(x/60/24/asize+0.5)*60*24*asize-xstart; // correct xret to number of minutes to closest first day of week since start date/time break; case 'm': // rounding to months var xstart = startdate.getMinutes()+startdate.getHours()*60; // correction needed to be sure that hours inside full day are skipped - if (actdate.getDate()'; + return cp; + }, getClipSettings: function(cliprange_in) { var clipsettings = {}; @@ -1644,7 +1808,7 @@ var widget_chart = { } else if (timeformat.search('dd')>-1 || timeformat.search('ee')>-1) { // time text will contain days, in case of auto shift we have an offset of half a day diff = 24*60/2; } else if (timeformat.search('MM')>-1) { // time text will contain months, in case of auto shift we have an offset of half a month - diff = time.getDaysInMonth()*24*60/2; + diff = time.myGetDaysInMonth()*24*60/2; } else if (timeformat.search('yy')>-1) { // time text will contain years, in case of auto shift we have an offset of half a month diff = (time.isLeapYear()?366:365)*24*60/2; } @@ -1673,9 +1837,10 @@ var widget_chart = { var el = elem.find('[class*=yaxis_'+uaxis+'-'+ind+']'); // find object fitting to actual yaxis slot if (el.length > 0) { var axisPar = (uaxis!='secondary')?val.primary:val.secondary; - var xshift = (axisPar.yticks_prio)?0:((uaxis!='secondary')?-cyclicSum(data.textWidth_prim,index,ind-1):cyclicSum(data.textWidth_sec,index,ind-1)); + var xshift = (axisPar.yticks_prio)?0:((uaxis!='secondary')?-(data.unusedYAxesVisible?cyclicSum(data.textWidth_prim,index,ind-1):0):(data.unusedYAxesVisible?cyclicSum(data.textWidth_sec,index,ind-1):0)); + var opacity = data.unusedYAxesVisible?1:((uaxis!='secondary')?(ind==index?1:0):(ind==index?1:0)); var style = el.attr('style'); - style = style.replace(/translateX\(.*\)/,'translateX('+xshift+'px)'); + style = data.unusedYAxesVisible?style.replace(/translateX\(.*\)/,'translateX('+xshift+'px)'):style.replace(/opacity\:.*\;/,'opacity:'+opacity+';'); el.attr('style',style); } }); @@ -1689,17 +1854,136 @@ var widget_chart = { widget_chart.getBrowserCaps().doSVGTransformCorrection(elem); + }, + resetTime: function(event) { + var elem = $(event.delegateTarget); + var baseobject = elem.closest("[class^=basesvg]").parent(); + var data = baseobject.data(); + + if (data.iZoom === undefined || data.iZoom < 0) return; + + data.daysago_start_old = data.daysago_start; + data.daysago_end_old = data.daysago_end; + data.daysago_start = data.daysago_start_list[data.iZoom]; + data.daysago_end = data.daysago_end_list[data.iZoom]; + + data.iZoom--; + if (data.iZoom<0) data.iZoom = 0; + + baseobject.data(data); + + widget_chart.zoomTimeAnimated(baseobject,0,20,function(){ + if (data.iZoom == 0) data.nofulldays = data.nofulldays_old; + }); + + return; + }, + zoomTime: function(event) { + var elem = $(event.delegateTarget); + var baseobject = elem.closest("[class^=basesvg]").parent(); + var data = baseobject.data(); + var xleft = elem.data('xleft'); + var xright = elem.data('xright'); + + if (!xleft.getDate) return; + if (!xright.getDate) return; + + if (data.iZoom === undefined || data.iZoom < 0) { + data.iZoom = 0; + data.daysago_start_list = []; + data.daysago_end_list = []; + } else { + data.iZoom++; + } + + data.daysago_start_list[data.iZoom] = data.daysago_start; + data.daysago_start_old = data.daysago_start; + data.daysago_start = xleft.getDateStringFHEM(); + + data.daysago_end_list[data.iZoom] = data.daysago_end; + data.daysago_end_old = data.daysago_end; + data.daysago_end = xright.getDateStringFHEM(); + + data.nofulldays_old = data.nofulldays; + data.nofulldays = true; + + baseobject.data(data); + + widget_chart.zoomTimeAnimated(baseobject,0,20,function(){}); + + return; + }, + zoomTimeAnimated: function(elem,index,steps,callback) { + var data = elem.data(); + data.offsetX = 0; // offset for shifting arbitrarily due to mousemove and touchmove handling + data.scaleX = 1; // scale for scaling arbitrarily due to mousemove and touchmove handling + data.scaleDeltaX = 0; // scale for scaling arbitrarily due to mousemove and touchmove handling + + var days_start_old = widget_chart.getDaysAgo(data.daysago_start_old,data); + var days_start = widget_chart.getDaysAgo(data.daysago_start,data); + var days_end_old = widget_chart.getDaysAgo(data.daysago_end_old,data); + var days_end = widget_chart.getDaysAgo(data.daysago_end,data); + + + setTimeout(function() { + if (index <= steps) { + var ds = days_start_old*(steps-index)/steps+days_start*index/steps; + var de = days_end_old*(steps-index)/steps+days_end*index/steps; + var scl = (days_end_old - days_start_old)/(de - ds); + var dlt = -(days_start_old-ds)*scl*24*60; // new delta in minutes + dlt = dlt/data.xrange*data.basewidth*data.graphWidth/100-data.getGraphLeft()*(scl-1); // new delta in pixels + + widget_chart.shiftXContent(elem,data.offsetX,scl,dlt,data) + index++; + widget_chart.zoomTimeAnimated(elem,index,steps,callback); + } else { + widget_chart.refresh(elem,'start reset',0); + callback(); + var theDoc = (data.popup)?elem:$(document); + theDoc.find("[class^=basesvg]").each(function() { + if ($(this).parent().is(':visible')) { + if (($(this).parent().data().scrollgroup == data.scrollgroup) && data.scrollgroup!==undefined && data.instance!=$(this).parent().data().instance && $(this).parent().data().baseDone) { + $(this).parent().data('daysago_start',data.daysago_start); + $(this).parent().data('daysago_end',data.daysago_end); + widget_chart.refresh($(this).parent(),'start reset',0); + } + } + }); + } + },2000/steps); + }, showHideGridlines: function(event) { // helper function to prepare for toggle gridline display when axis string is clicked var elem = $(event.delegateTarget); var data = elem.closest("[class^=basesvg]").parent().data(); + var isPrimary = (elem.attr('class').search('primary')>-1); var AI = parseInt(elem.attr('class').replace(/.*-/,'')); $.each(data.yLimits, function(ind,val){ this.primary.yticks_prio = false; this.secondary.yticks_prio = false; }); - if (elem.attr('class').search('primary')>-1) { + if (!data.unusedYAxesVisible) { // we need to find the next axis of the selected type and display this axis + var elaxes = elem.parent() + elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'')+"]").each(function() { + if ($(this).css('opacity') == 1) AI = parseInt($(this).attr('class').replace(/.*-/,'')) // find currently visible axis + }); + if (elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'-'+parseInt(AI+1))+"]").length > 0) { // there is an axis with higher AI, take this one + AI++; + } else { // no axis with higher index, take lowest one + var xs = elaxes.find("[class*="+elem.attr('class').replace(/.*yaxis/,'yaxis').replace(/-.*/,'')+"]"); + var AI = Infinity; + xs.each(function() { + var aindex = parseInt($(this).attr('class').replace(/.*-/,'')); + if (aindex < AI) AI = aindex; + }); + if (AI == Infinity) AI = 0; + } + + if (AI > data.yLimits.length-1) AI = 0; + } + + if (isPrimary) { data.yLimits[AI].primary.yticks_prio = true; } else { data.yLimits[AI].secondary.yticks_prio = true; @@ -1707,9 +1991,298 @@ var widget_chart = { widget_chart.doShowHideGridlines(data,elem.closest("[class^=basesvg]").parent()); }, + shiftXContent: function(_baseobject,_currentDistance,_currentScale,_currentScaleDelta,_data,noprop) { + if (!_data.DDD || !_data.graphArea) return; + var scale = _currentScale; + var offset = _currentScaleDelta; + var subobject = _baseobject.find("[id=baseforDDD]"); + _data.startXMove = _currentDistance; + _data.offsetX = _currentDistance; + _data.scaleX = _currentScale; + _data.scaleDeltaX = _currentScaleDelta; + + var transform2position = function(e,d,o) { + if (e.attr('x1')) { // line + if (e.attr('x1_orig') === undefined) e.attr({'x1_orig':e.attr('x1')}); + if (e.attr('x2_orig') === undefined) e.attr({'x2_orig':e.attr('x2')}); + var x1 = parseInt(e.attr('x1_orig')||e.attr('x_orig')); + var x2 = parseInt(e.attr('x2_orig')||e.attr('x_orig')); + x1 = x1*d.scaleX+d.offsetX+o; + x2 = x2*d.scaleX+d.offsetX+o; + e.attr({'x1':x1,'x2':x2}); + } else if (e.attr('x')) { // point + if (e.attr('x_orig') === undefined) e.attr({'x_orig':e.attr('x')}); + var x = parseInt(e.attr('x1_orig')||e.attr('x_orig')); + x = x*d.scaleX+d.offsetX+o; + e.attr({'x':x}); + } + } + + var distance = _currentDistance + offset; + subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); + subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,offset);}); + subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,offset);}); + + var distance = _currentDistance-_data.graphArea.width*scale + offset; + var subobject = _baseobject.find("[id=baseforDDD-previous]"); + subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); + subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,-_data.graphArea.width*scale+offset);}); + subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,-_data.graphArea.width*scale+offset);}); + + var distance = _currentDistance+_data.graphArea.width*scale + offset; + var subobject = _baseobject.find("[id=baseforDDD-next]"); + subobject.find("svg.chart-primsec").find("g.graph-parent").css(_data.DDD.prefix+'transform','translate('+distance+'px, 0px)'+' scale('+scale+',1)'); + subobject.find("g.text.xaxis").children().each(function() {transform2position($(this),_data,_data.graphArea.width*scale+offset);}); + subobject.find("g.chart-gridlines").find("line.xticks").each(function() {transform2position($(this),_data,_data.graphArea.width*scale+offset);}); + + // check if other charts are in the same scrollgroup and shift them as well + if (!noprop) { + var theDoc = (_data.popup)?_baseobject:$(document); + theDoc.find("[class^=basesvg]").each(function() { + if ($(this).parent().is(':visible')) { + var data = $(this).parent().data(); + if ((data.scrollgroup == _data.scrollgroup) && _data.scrollgroup!==undefined && _data.instance!=data.instance && data.baseDone) { + widget_chart.shiftXContent($(this),_currentDistance,_currentScale,_currentScaleDelta,data,true); + } + } + }); + } + }, + detectSwipe: function(target,remove) { // helper function to handle swipe and pinch events + var maxTime = 1000, // allow movement if < 1000 ms (1 sec) + startX = 0, + startXMove = 0, + startScaleX = 1, + startTime = 0, + lastTap = 0, + scaling = false, + pinchDist = 0, + timeout, + startTouches = [], + startLeftOffset = [], + touch = "ontouchend" in document, + startEvent = (touch) ? 'touchstart' : 'mousedown', + moveEvent = (touch) ? 'touchmove' : 'mousemove', + pinchEvent = (touch) ? 'gestureend' : '', + endEvent = (touch) ? 'touchend' : 'mouseup'; + var e = false; + + target.on(startEvent, function(_e){ + if (!_e.originalEvent.touches) { // no 2 finger gestures are suppoprted, simulate it. + if (!e) e = {timeStamp:_e.timeStamp, delegateTarget:_e.delegateTarget, preventDefault:_e.preventDefault, ctrlKey:_e.ctrlKey, stopPropagation:_e.stopPropagation, originalEvent:{touches:[]}}; + e.ctrlKey = _e.ctrlKey; + e.originalEvent.touches[0] = { + pageX:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX, + pageY:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY}; + e.originalEvent.touches[1] = { + pageX:(_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX)-100, + pageY:(_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY)-100}; + e.timeStamp = _e.timeStamp; + } else { + e = _e; + } + //console.log("Start Event",e); + // prevent image drag (Firefox) + var baseobject = $(e.delegateTarget).parents("[class^=basesvg]").parent(); + var data = baseobject.data(); + if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. + + _e.preventDefault(); + _e.stopPropagation(); + + startTime = e.timeStamp; + startX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; + startXMove = data.startXMove?data.startXMove:0; // keep actual shift in x direction in mind + data.movingX = true; + startScaleX = data.scaleX; + + if (e.originalEvent.touches && e.originalEvent.touches.length && e.originalEvent.touches.length === 2) { + if ((!_e.originalEvent.touches && e.ctrlKey) || _e.originalEvent.touches) { + scaling = true; + data.offsetX = data.offsetX + data.scaleDeltaX; + data.scaleDeltaX = 0; + } + startTouches[0] = e.originalEvent.touches[0].pageX; + startTouches[1] = e.originalEvent.touches[1].pageX; + } + baseobject.data(data); + }) + .on(endEvent, function(_e){ + //console.log("End Event",e); + var baseobject = $(_e.delegateTarget).parents("[class^=basesvg]").parent(); + var data = baseobject.data(); + if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. + if (data.crosshair) return; + + _e.preventDefault(); + _e.stopPropagation(); + + var currentTime = new Date().getTime(); + var tapLength = currentTime - lastTap; + + clearTimeout(timeout); + if (tapLength < 500 && tapLength > 0){ // double click/tap, reset interactive scaling/shifting + + scaling = false; + data.movingX = false; + startX = 0; + widget_chart.shiftXContent(baseobject,0,1,0,data); + + } else { + + //Single Tap/Click + + timeout = setTimeout(function(){ + clearTimeout(timeout); + }, 500); + } + + lastTap = currentTime; + + scaling = false; + startX = 0; + startTime = 0; + data.movingX = false; + baseobject.data(data); + + }) + .on(moveEvent, function(_e){ + if (!_e.originalEvent.touches) { // no 2 finger gestures are suppoprted, simulate it. + if (!e) e = {timeStamp:_e.timeStamp, delegateTarget:_e.delegateTarget, preventDefault:_e.preventDefault, ctrlKey:_e.ctrlKey, stopPropagation:_e.stopPropagation, originalEvent:{touches:[]}}; + e.ctrlKey = _e.ctrlKey; + e.originalEvent.touches[0] = { + pageX:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageX : _e.pageX, + pageY:_e.originalEvent.touches ? _e.originalEvent.touches[0].pageY : _e.pageY}; + } else { + e = _e; + } + + //console.log("Move Event",e); + var baseobject = $(e.delegateTarget).parents("[class^=basesvg]").parent(); + var data = baseobject.data(); + if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. + + _e.preventDefault(); + _e.stopPropagation(); + + var started = data.movingX; + if (!started) return; + var maxDistance = data.graphArea.width - (data.prefetch?1:50); // start reloading new data when distance to chart border is lower than 50 pixels + + if (data.crosshair) return; + + var getScaleDelta = function(current,start,scale,left) { + var startLeftOffset = [start[0]-left,start[1]-left]; + var currentLefOffset = [current[0]-left,current[1]-left]; + return ((currentLefOffset[0] - startLeftOffset[0]*scale)+(currentLefOffset[1] - startLeftOffset[1]*scale))/2; + } + + if (scaling) { + var newTouches = [e.originalEvent.touches[0].pageX, e.originalEvent.touches[1].pageX]; + var scaleCurrent = (newTouches[0] - newTouches[1])/(startTouches[0] - startTouches[1]); + var scaleX = scaleCurrent*startScaleX; + + var delta = getScaleDelta(newTouches,startTouches,scaleCurrent,data.graphArea.left); + + if (!data.DDD.has3D) { // no transform feature, so we can not use the live movement of the graphs. + if (scaleX < 0.9) { + widget_chart.scaleTime(e,baseobject,2); + data.movingX = false; + scaling = false; + startX = 0; + scaleX = 1; + } else if (scaleX > 1.1) { + widget_chart.scaleTime(e,baseobject,0.5); + data.movingX = false; + scaling = false; + startX = 0; + scaleX = 1; + } + return; + } + + if (scaleX < 0.5) { + scaling = false; + data.movingX = false; + startX = 0; + scaleX = 1; + startTime = 0; + var offsetX = data.offsetX; + widget_chart.scaleTime(e, baseobject, 2, true, true, function() { + widget_chart.shift(e, baseobject, 0, true, false, function(){ + data = baseobject.data(); + widget_chart.shiftXContent(baseobject,(offsetX),scaleX,0,data); + }); + }); + } else if (scaleX > 2) { + scaling = false; + data.movingX = false; + startX = 0; + scaleX = 1; + startTime = 0; + var offsetX = data.offsetX; + widget_chart.scaleTime(e, baseobject, 0.5, true, true, function() { + widget_chart.shift(e, baseobject, 0, true, false, function(){ + data = baseobject.data(); + widget_chart.shiftXContent(baseobject,(offsetX),scaleX,0,data); + }); + }); + } else { + widget_chart.shiftXContent(baseobject,data.offsetX,scaleX,delta,data); + } + } else { + var currentX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX, + currentDistance = (startX === 0) ? 0 : (currentX - startX + startXMove), + // allow if movement < 1 sec + currentTime = e.timeStamp; + + if (!data.DDD.has3D) { // no transform feature, so we can not use the live movement of the graphs. + if (Math.abs(currentDistance) > 100) { + if (currentX < startX) { + widget_chart.shift(e, baseobject, -1, true); + } + + if (currentX > startX) { + widget_chart.shift(e, baseobject, 1, true); + } + data.movingX = false; + startTime = 0; + startX = 0; + } + return; + } + + widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); + + // currentDistance = (startX === 0) ? 0 : Math.abs(currentX - startX), + // allow if movement < 1 sec + currentTime = e.timeStamp; + if (Math.abs(currentDistance) > maxDistance) { + if (currentX < startX) { + // swipe left code here + widget_chart.shift(e, baseobject, -1, true, false, function() { + currentDistance = 0; + widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); + }); + } + if (currentX > startX) { + // swipe right code here + widget_chart.shift(e, baseobject, 1, true, false, function() { + currentDistance = 0; + widget_chart.shiftXContent(baseobject,currentDistance,data.scaleX,data.scaleDeltaX,data); + }); + } + data.movingX = false; + startTime = 0; + startX = 0; + } + } + }); + }, checkEvent: function(event) { // helper function to do some special treatments/preparations for events event.preventDefault(); - var data = $(event.delegateTarget).parents("[class^=basesvg]").parent().data; + var data = $(event.delegateTarget).parents("[class^=basesvg]").parent().data(); + if (!data.done || !data.baseDone || data.drawing) return; // check if we already have done one successful drawing or if we are in the middle of redraw. if (!data.last_mousemove_pos) data.last_mousemove_pos = {'x':-1,'y':-1}; var x = event.pageX; @@ -1730,13 +2303,31 @@ var widget_chart = { theDoc.find("[class^=basesvg]").each(function() { if ($(this).parent().is(':visible')) { var data = $(this).parent().data(); - if ((data.cursorgroup == dataE.cursorgroup) && dataE.cursorgroup!==undefined && dataE.instance!=data.instance) { + if ((data.cursorgroup == dataE.cursorgroup) && dataE.cursorgroup!==undefined && dataE.instance!=data.instance && data.baseDone) { var dShift = data.days_start-dataE.days_start; var sc = data.days_start-data.days_end; var scW = data.graphArea.width/dataE.graphArea.width; var e = $.Event(event.type); - if (event.originalEvent) e.originalEvent = event.originalEvent; - e.pageX = data.graphArea.left + ((event.pageX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW; + if (event.originalEvent && event.originalEvent.touches) { + e.originalEvent = JSON.parse(JSON.stringify(event.originalEvent)); + if (event.originalEvent.touches && event.originalEvent.touches[0]) { + var x = data.graphArea.left + ((event.originalEvent.touches[0].pageX-dataE.offsetX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW+data.offsetX+data.scaleDeltaX; + var point = {x: x, y: event.originalEvent.touches[0].pageY }; + + e.originalEvent.touches = [{ + target: event.originalEvent.target, + identifier: event.originalEvent.identifier, + pageX: x, + pageY: event.originalEvent.touches[0].pageY, + screenX: x, + screenY: event.originalEvent.touches[0].pageY, + clientX: x, + clientY: event.originalEvent.touches[0].pageY + }] + } + } else { + e.pageX = data.graphArea.left + ((event.pageX-dataE.offsetX-dataE.graphArea.left)*scE/sc + (dShift/sc)*dataE.graphArea.width)*scW+data.offsetX+data.scaleDeltaX; + } e.delegateTarget = $(this).find("rect.chart-background, [id*='graph-']"); widget_chart.doEvent(e); } @@ -1754,6 +2345,7 @@ var widget_chart = { var values = []; var ind; var prefix; + var p_n_offset; crht.each(function(index) {crh_text[index] = $(this);}); switch (event.type) { // split into different activities for different events @@ -1769,7 +2361,8 @@ var widget_chart = { if (data.crosshair) { //console.log("Mouseenter Event",$(event.delegateTarget).parents("[class^=basesvg]").parent().data'crs_inactive')); if (crosshair && !data.crs_inactive && data.pointsarrayCursor) { - var x = (evt.pageX - data.chartArea.left); + var x = ((evt.pageX - data.chartArea.left)); +// var x = ((evt.pageX - data.chartArea.left - data.offsetX) - data.graphArea.width*(1-data.scaleX))/data.scaleX) - data.graphArea.width*(1-data.scaleX))/data.scaleX; var y = (evt.pageY - data.chartArea.top); var noticks = ( data.width <=100 ) ? true : target.parent().hasClass('noticks'); if (data.logProxy) { @@ -1784,21 +2377,47 @@ var widget_chart = { //crosshair.find('line.crosshair').attr({'x1':x, 'y1':data.topOffset, 'x2':x, 'y2':data.chartArea.height-(noticks?0:data.bottomOffset)}); widget_chart.movetoLine(event.type,crosshair.find('line.crosshair'),x,data.topOffset,x,data.chartArea.height-(noticks?0:data.bottomOffset),100,function(x1f,y1f,x2f,y2f){}); values=[]; - ind = ((parseInt(x+0.5)<=0)?0:((parseInt(x+0.5)>=data.pointsarrayCursor.length)?data.pointsarrayCursor.length-1:(parseInt(x+0.5)))); - values = data.pointsarrayCursor[ind]; + ind = parseInt((x-data.getOffsetX())/data.scaleX+0.5); + if (ind < parseInt(data.graphArea.left-data.chartArea.left+0.5)) { + if (data.pointsarrayCursor_prev && data.pointsarrayCursor_prev.length) { + ind = parseInt(Math.max(ind+data.graphArea.width,0)+0.5); + values = data.pointsarrayCursor_prev[ind]; + p_n_offset = -data.graphArea.width*data.scaleX+data.getOffsetX(); + } else { + values = data.pointsarrayCursor[0]; + p_n_offset = data.getOffsetX(); + } + } else if (ind >= data.pointsarrayCursor.length) { + if (data.pointsarrayCursor_prev && data.pointsarrayCursor_prev.length) { + ind = parseInt(Math.min(ind-data.graphArea.width,data.pointsarrayCursor_next.length)+0.5); + values = data.pointsarrayCursor_next[ind]; + p_n_offset = data.graphArea.width*data.scaleX+data.getOffsetX(); + } else { + values = data.pointsarrayCursor[data.pointsarrayCursor.length-1]; + p_n_offset = data.getOffsetX(); + } + } else { + values = data.pointsarrayCursor[ind]; + p_n_offset = data.getOffsetX(); + } + //ind = ((parseInt(x+0.5)<=0)?0:((parseInt(x+0.5)>=data.pointsarrayCursor.length)?data.pointsarrayCursor.length-1:(parseInt(x+0.5)))); + //values = data.pointsarrayCursor[ind]; } var lastV = data.lastV; var uxis; var i,il; var legendY; + var minclip = data.graphArea.top - data.chartArea.top; + var maxclip = data.graphArea.height + minclip; if (!lastV) lastV = values; + if (!values) values = []; for (i=0,il=values.length; i=minclip && legendY<=maxclip) { crh_text[i].show(); crh_text[i].find('tspan.crosshairValue').html(valtxt); } else { crh_text[i].hide(); } - widget_chart.moveto(crh_text[i],values[i][0],legendY,50,function(xf,yf){}); + widget_chart.moveto(crh_text[i],values[i][0]*data.scaleX+p_n_offset,legendY,50,function(xf,yf){}); /* var rw = widget_chart.getTextSizePixels(target,prefix + valtxt,'text crosshair').width; var rh = widget_chart.getTextSizePixels(target,prefix + valtxt,'text crosshair').height; if (!crh_text[i].parent().find('rect').length) { @@ -1835,7 +2454,7 @@ var widget_chart = { if (!data.logProxy) { // draw time value below x axis var itime=crh_text.length-1; legendY = data.graphHeight/100*target.height()+data.topOffset+widget_chart.getTextSizePixels(crh_text[itime].parents("[class^=basesvg]"),'O','crosshair').height; - var xminutes = (x-data.getGraphLeft())*100/data.basewidth*data.xrange/data.graphWidth; + var xminutes = ((x-data.getOffsetX())/data.scaleX-data.getGraphLeft())*100/data.basewidth*data.xrange/data.graphWidth; var tstart = ftui.dateFromString(data.mindate); var tx = new Date(tstart); var textX2Value, tarr; @@ -1853,7 +2472,8 @@ var widget_chart = { var rw = widget_chart.getTextSizePixels(target,textX2Value,'text crosshair').width; var rh = widget_chart.getTextSizePixels(target,textX2Value,'text crosshair').height; if (!crh_text[itime].parent().find('rect').length) { - crh_text[itime].parent().prepend(widget_chart.createElem('rect').attr({'class':'crosshair','x':x-rw/2,'y':legendY-rh/2,'width':rw+'px','height':rh+'px','style':'z-index:10000; fill:black'})); + crh_text[itime].parent().prepend(widget_chart.createElem('rect').attr({'class':'crosshair','x':x-rw/2,'y':legendY-rh/2,'width':rw+'px','height':rh+'px','style':'z-index:10000; fill:black;'})); + crh_text[itime].parent().find('rect.crosshair').parent().css('clip-path','none'); crh_text[itime].attr({'text-anchor':'middle'}); } crh_text[itime].parent().find('rect').attr({'x':x-rw/2, 'y':legendY-rh/2}); @@ -1910,19 +2530,21 @@ var widget_chart = { calcDiffMonth: function(ds,de,offset) { var width = Math.abs(ds-de); var now = new Date(); - var tstart = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); - var tend = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); - tstart.setTime(tstart.getTime() - (Math.max(ds,de)*24*60*60*1000)); - tend.setTime(tend.getTime() - (Math.min(ds,de)*24*60*60*1000)); + var tstart = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); // get current time rounded to minutes + var tend = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),0,0); // get current time rounded to minutes + tstart.setTime(tstart.getTime() - (Math.max(ds,de)*24*60*60*1000)); // set tstart to maximum of ds/de less than current time + tend.setTime(tend.getTime() - (Math.min(ds,de)*24*60*60*1000)); // set tstart to minimum of ds/de less than current time var ret = []; - if (width >= tstart.getDaysInMonth()) { - var mdiff = tend.getMonth()-tstart.getMonth()+(tend.getFullYear()-tstart.getFullYear())*12; - var dateS = (tstart.getDate()==tstart.getDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-mdiff*offset,1,0,0,0,0).getDaysInMonth():tstart.getDate(); - var dateE = (tend.getDate()==tend.getDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-mdiff*offset,1,0,0,0,0).getDaysInMonth():tend.getDate(); - - ret[0] = ds + widget_chart.dateDiff(new Date(tstart.getFullYear(),tstart.getMonth()-mdiff*offset,dateS,tstart.getHours(),tstart.getMinutes(),0,0),tstart,'d'); - ret[1] = de + widget_chart.dateDiff(new Date(tend.getFullYear(),tend.getMonth()-mdiff*offset,dateE,tend.getHours(),tend.getMinutes(),0,0),tend,'d'); + if (width >= tstart.myGetDaysInMonth()) { // difference is bigger than current month care for correct treatment + var mdiff = tend.getMonth()-tstart.getMonth()+(tend.getFullYear()-tstart.getFullYear())*12; // get number of months between dates + var md = parseInt(mdiff*offset); + var dds = (mdiff*offset-md)*tstart.myGetDaysInMonth(); + var dde = (mdiff*offset-md)*tend.myGetDaysInMonth(); + var dateS = (tstart.getDate()==tstart.myGetDaysInMonth())?new Date(tstart.getFullYear(),tstart.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tstart.getDate(); + var dateE = (tend.getDate()==tend.myGetDaysInMonth())?new Date(tend.getFullYear(),tend.getMonth()-md,1,0,0,0,0).myGetDaysInMonth():tend.getDate(); + ret[0] = ds + widget_chart.dateDiff(new Date(tstart.getFullYear(),tstart.getMonth()-md,dateS-dds,tstart.getHours(),tstart.getMinutes(),0,0),tstart,'d'); + ret[1] = de + widget_chart.dateDiff(new Date(tend.getFullYear(),tend.getMonth()-md,dateE-dde,tend.getHours(),tend.getMinutes(),0,0),tend,'d'); } else { ret[0] = ds + offset*width; ret[1] = de + offset*width; @@ -1949,17 +2571,22 @@ var widget_chart = { data.days_end = dRet[1]; break; default: - width = data.days_start-data.days_end; + width = (data.days_start-data.days_end); data.days_start = data.days_start+offset*(width); data.days_end = data.days_end+offset*(width); break; } }, - shift: function(evt,elem,offset){ // calculate new start and end dates when user wants to shift graph + shift: function(evt,elem,offset,noanimation,norefresh,callback){ // calculate new start and end dates when user wants to shift graph var dataE = elem.data(); + if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. dataE.shift += offset; - widget_chart.doCorrectShift(dataE, offset); - widget_chart.refresh(elem,'shift',-offset); + //widget_chart.doCorrectShift(dataE, offset); + if (!norefresh) { + widget_chart.refresh(elem,noanimation?'start reset':'shift',-offset,callback); + } else { + if (callback) callback(); + } // check if other charts are in the same scrollgroup and shift them as well var theDoc = (dataE.popup)?elem:$(document); @@ -1967,13 +2594,18 @@ var widget_chart = { var data = $(this).parent().data(); if ((data.scrollgroup == dataE.scrollgroup) && dataE.scrollgroup!==undefined && dataE.instance!=data.instance) { data.shift += offset; - widget_chart.doCorrectShift(data, offset); - widget_chart.refresh($(this).parent(),'shift',-offset); + //widget_chart.doCorrectShift(data, offset); + if (!norefresh) { + widget_chart.refresh($(this).parent(),noanimation?'start reset':'shift',-offset,callback); + } else { + if (callback) callback(); + } } }); }, rotate: function(evt,elem,rotx,roty){ // calculate new rotation values when 3D modus is activated var dataE = elem.data(); + if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. if (dataE.ddd === undefined) { return; @@ -2001,7 +2633,7 @@ var widget_chart = { doCorrectScale: function(data,scale) { // helper function for correction of scale due to given classifier ('y','m') var classifier = data.xclassifier; var width; - if (classifier == 'y' && (data.days_start-data.days_end)<365*2) classifier = 'm'; // if we will have less than one year difference use rounding to months instead of rounding to years + if (classifier == 'y' && (data.days_start-data.days_end)<365*2) classifier = 'm'; // if we will have less than two years difference use rounding to months instead of rounding to years switch (classifier) { case 'y': // correction needed for leap years width = widget_chart.correctLeapYear(data.days_start,data.days_end,'down'); // remove leap year days for old period @@ -2011,7 +2643,7 @@ var widget_chart = { break; case 'm': // correction needed due to different number of days per month width = data.days_start-data.days_end; - if (width>31 || scale > 1) { // new difference is more than a month => use calculated value + if (width>31 || scale > 1) { // new difference is surely more than a month => use corrected value var dRet = widget_chart.calcDiffMonth(data.days_start,data.days_end,scale-1); data.days_start = dRet[0]; } else { // do calculation without month correction @@ -2031,19 +2663,19 @@ var widget_chart = { if (!$.isArray(dataE.timeranges)) return; // there is no definition of timeranges, do nothing var selBtn = $(evt.delegateTarget); - widget_chart.doLog("widget_chart.selectTime","test: "+window.pageXOffset+", "+window.pageYOffset); + //widget_chart.doLog("widget_chart.selectTime","test: "+window.pageXOffset+", "+window.pageYOffset); //elem.find("[id='selectTimePulldown_"+dataE.instance+"']").remove(); // remove old pulldown if it is still there. var pulldownMenu = elem.find("[id='selectTimePulldown_"+dataE.instance+"']"); if (!pulldownMenu.length || pulldownMenu.length == 0) { pulldownMenu = $(document.createElement('div')).attr({ - 'style': 'width: auto; display:none; position: absolute; left:'+ - (evt.pageX-elem.parent().offset().left)+'px; top:'+ - (evt.pageY-elem.parent().offset().top)+'px;', + 'style': 'width: auto; display:none; position: absolute; z-index: 10000; left:'+ + (elem.find('.buttons.timeranges').offset().left-elem.offset().left)+'px; top:'+ + (elem.find('.buttons.timeranges').offset().top-elem.offset().top+elem.find('.buttons.timeranges')[0].getBoundingClientRect().height)+'px;', 'class': 'pulldownmenu', 'id': 'selectTimePulldown_'+dataE.instance }); $.each( dataE.timeranges, function( ind, value ) { - var pdEntry = $(document.createElement('div')).attr({'class':"pdentry"}); + var pdEntry = $(document.createElement('div')).attr({'class':"pdentry",'style':'z-index: 10000;'}); pdEntry.text(value[0]); pulldownMenu.append(pdEntry); pdEntry.data('timerrange',value); @@ -2056,7 +2688,8 @@ var widget_chart = { elem.data('daysago_end',$(e.delegateTarget).data('timerrange')[2]); elem.data('scale', 1); // set scale value to initial value elem.data('shift', 0); // set shift value to initial value - widget_chart.refresh(elem,'start',0); + elem.data('iZoom',-1); // reset zoom array used when clicking at x-axis labels + widget_chart.refresh(elem,'start reset',0); // check if other charts are in the same scrollgroup and shift them as well var theDoc = (dataE.popup)?elem:$(document); @@ -2068,7 +2701,8 @@ var widget_chart = { elm.data('daysago_end',$(e.delegateTarget).data('timerrange')[2]); elm.data('scale', 1); // set scale value to initial value elm.data('shift', 0); // set shift value to initial value - widget_chart.refresh($(this).parent(),'start',0); + elm.data('iZoom',-1); // reset zoom array used when clicking at x-axis labels + widget_chart.refresh($(this).parent(),'start reset',0); } }); } @@ -2079,25 +2713,33 @@ var widget_chart = { elem.append(pulldownMenu); } - pulldownMenu.slideDown(400,function() {$(document).bind('click.pdClicks', function(e) { + pulldownMenu.slideDown(400,function() {$(document).on('click.pdClicks', function(e) { pulldownMenu.hide(); - $(document).unbind('click.pdClicks'); + $(document).off('click.pdClicks'); })}); }, - scaleTime: function(evt,elem,scale){ // calculate new start and end dates when user wants to scale graph + scaleTime: function(evt,elem,scale,noanimation,norefresh,callback){ // calculate new start and end dates when user wants to scale graph var dataE = elem.data(); + if (!dataE.done || !dataE.baseDone || dataE.drawing) return; // check if we already have done one successful drawing. dataE.scale *= scale; - widget_chart.doCorrectScale(dataE,scale); - widget_chart.refresh(elem,'scale',0); - + //widget_chart.doCorrectScale(dataE,scale); + if (!norefresh) { + widget_chart.refresh(elem,noanimation?'start reset':'scale',0,callback); + } else { + if (callback) callback(); + } // check if other charts are in the same scrollgroup and scale them as well var theDoc = (dataE.popup)?elem:$(document); theDoc.find("[class^=basesvg]").each(function() { var data = $(this).parent().data(); if ((data.scrollgroup == dataE.scrollgroup) && dataE.scrollgroup!==undefined && dataE.instance!=data.instance) { data.scale *= scale; - widget_chart.doCorrectScale(data,scale); - widget_chart.refresh($(this).parent(),'scale',0); + //widget_chart.doCorrectScale(data,scale); + if (!norefresh) { + widget_chart.refresh($(this).parent(),noanimation?'start reset':'scale',0,callback); + } else { + if (callback) callback(); + } } }); }, @@ -2199,6 +2841,8 @@ var widget_chart = { currval += (currval maxwidth) {maxwidth = wdth;} lwidths[i] = wdth+2.5; sumwidth += lwidths[i]; @@ -2329,10 +2980,10 @@ var widget_chart = { legend_container.prepend(widget_chart.createElem('rect').attr({'class':'lback'})); legend_container.find('rect.lback') // add drag functionality for legend container .draggable() - .bind('mouseover', function(event) { + .on('mouseover', function(event) { event.target.setAttribute('style','cursor:move'); }) - .bind('mousedown touchstart', function(event, ui){ + .on('mousedown touchstart', function(event, ui){ var evt; // keep initial mouse position relative to draggable object. if (event.type == 'touchstart') { @@ -2345,7 +2996,7 @@ var widget_chart = { xS = parseFloat($(evt.target).attr('x')) - (evt.pageX - target.offset().left); yS = parseFloat($(evt.target).attr('y')) - (evt.pageY - target.offset().top); }) - .bind('drag touchmove', function(event, ui) { + .on('drag touchmove', function(event, ui) { var evt; if (event.type == 'touchmove') { if (!event.originalEvent) return; @@ -2373,7 +3024,7 @@ var widget_chart = { for (var k=0; k now.getTime())) { + data.filltime_end_save = data.filltime_end; + data.filltime_end = false; + } else { + data.filltime_end = data.filltime_end_save; + } + + data.baseDone = false; // chart has to be redrawn, set flag to control right order between 'acutal', 'previous' and 'next' + data.openDrawings = data.prefetch?3:1; // number of drawings to be done needed for checking when to activate event handling for scale and shift $(theObj).data(data); - widget_chart.retrieveData(elem,type,swoffset,data_old,'actual'); - if (data.prefetch) widget_chart.retrieveData(elem,type,swoffset,data_old,'previous'); - if (data.prefetch) widget_chart.retrieveData(elem,type,swoffset,data_old,'next'); + promiseAct = widget_chart.retrieveData(elem,type,swoffset,data_old,'actual',callback,true); + if (data.prefetch) { + promisePrev = widget_chart.retrieveData(elem,type,swoffset,data_old,'previous',callback,true); + promiseNext = widget_chart.retrieveData(elem,type,swoffset,data_old,'next',callback,true); + } + } else { + data.baseDone = false; // chart has to be redrawn, set flag to control right order between 'acutal', 'previous' and 'next' + data.openDrawings = data.prefetch?(type=='shift'?2:3):1; // number of drawings to be done needed for checking when to activate event handling for scale and shift + $(theObj).data(data); + widget_chart.drawChart(elem,type,swoffset,data_old,callback); + //if (data.prefetch && !(type=='shift' && swoffset==-1)) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous'); + //if (data.prefetch && !(type=='shift' && swoffset==1)) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next'); + } + if ((data.filltime_start || data.filltime_end) && data.prefetch) { // we need to correct the "artificial" data points and thus need to wait for all d + $.when(promiseAct,promiseNext,promisePrev).done(function() { + widget_chart.drawChart(elem,type,swoffset,data_old,callback); + if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous'); + if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next'); + }); } else { - widget_chart.drawChart(elem,type,swoffset,data_old); + $.when(promiseAct,promisePrev).done(function() {if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'previous');}); + $.when(promiseAct,promiseNext).done(function() {if (data.prefetch) widget_chart.drawChart(elem,type,swoffset,data_old,callback,'next');}); } }, - retrieveData: function(elem,type,swoffset,data_old,cachetype) { + retrieveData: function(elem,type,swoffset,data_old,cachetype,callback,draw) { var theObj; - if (elem) theObj=elem; else theObj=this; + if (elem) theObj=elem; else theObj=this; var data = $(theObj).data(); - //check the input arrays to derive the one with biggest length data.nGraphs = widget_chart.getnGraphs(data); + var deferred = new $.Deferred(); + $(theObj).data('runningRefresh',true); for (var k=0; k 0) data.nofilldown[slot] = true; // there is a columnspec given as array, do not fill down to x-axes but fill area between the 2 curves + if (($(theObj).data().filltime_start || $(theObj).data().filltime_end) && points.length && points.length > 0) { // add additional data points at beginning and end of chart area + var fillstart = (data.filltime_start && (cachetype == 'actual' || cachetype == 'previous')) || (data.filltime_end && cachetype == 'next'); + var fillend = (data.filltime_end && (cachetype == 'actual' || cachetype == 'next')) || (data.filltime_start && cachetype == 'previous'); + if (points[1][0] != 0 && fillstart) { + points[0] = points[1].clone(); + points[0][0] = 0; + } else { // first point is already at leftmost position, shift the array + points.shift(); + } + if (points[points.length-1][0] != ftui.diffMinutes(tstart,tend) && fillend) { + points[points.length] = points[points.length-1].clone(); + points[points.length-1][0] = ftui.diffMinutes(tstart,tend); + } + } + + if (ics > 0) $(theObj).data().nofilldown[slot] = true; // there is a columnspec given as array, do not fill down to x-axes but fill area between the 2 curves - data.columnspecsDone[cachetype][slot]++; + $(theObj).data().columnspecsDone[cachetype][slot]++; if (cachetype == 'previous') { - data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray_prev,data.pointsstr_prev,points,points_str,ics,data.last_ics[cachetype][slot]); - if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx_prev++; // all columnspecs for this slot are processed, count up slot - $(theObj).data(data); - if (data.kIndx_prev==data.nGraphs) data.previous_cache_completed = true; + $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray_prev,$(theObj).data().pointsstr_prev,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); + if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx_prev++; // all columnspecs for this slot are processed, count up slot + if ($(theObj).data().kIndx_prev==$(theObj).data().nGraphs) { + $(theObj).data().previous_cache_completed = true; + deferred.resolve(); + } } else if (cachetype == 'next') { - data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray_next,data.pointsstr_next,points,points_str,ics,data.last_ics[cachetype][slot]); - if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx_next++; // all columnspecs for this slot are processed, count up slot - $(theObj).data(data); - if (data.kIndx_next==data.nGraphs) data.next_cache_completed = true; + $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray_next,$(theObj).data().pointsstr_next,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); + if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx_next++; // all columnspecs for this slot are processed, count up slot + if ($(theObj).data().kIndx_next==$(theObj).data().nGraphs) { + $(theObj).data().next_cache_completed = true; + deferred.resolve(); + } } else { - data.last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,data.pointsarray,data.pointsstr,points,points_str,ics,data.last_ics[cachetype][slot]); - if (data.columnspecsDone[cachetype][slot]==icsl) data.kIndx++; // all columnspecs for this slot are processed, count up slot - $(theObj).data(data); - if (data.kIndx==data.nGraphs) { // last slot to be retrieved start painting chart - widget_chart.drawChart(elem,type,swoffset,data_old); + $(theObj).data().last_ics[cachetype][slot] = widget_chart.joinGraphs(slot,$(theObj).data().pointsarray,$(theObj).data().pointsstr,points,points_str,ics,$(theObj).data().last_ics[cachetype][slot]); + if ($(theObj).data().columnspecsDone[cachetype][slot]==icsl) $(theObj).data().kIndx++; // all columnspecs for this slot are processed, count up slot + if ($(theObj).data().kIndx==$(theObj).data().nGraphs) { // last slot to be retrieved start painting chart + if (!(($(theObj).data().filltime_start || $(theObj).data().filltime_end) && $(theObj).data().prefetch)) widget_chart.drawChart(theObj,type,swoffset,data_old,callback); + deferred.resolve(); } } //last point is repetition of column spec, dont add @@ -2710,12 +3434,81 @@ var widget_chart = { }); } } + return deferred.promise(); }, - drawChart: function (elem,type,swoffset,data_old) { // main function for generation of all HTML code and dynamics for graph called whenever thigs change (e.g. data update, shift, scale, ...) + interpolate: function(leftx,lefty,rightx,righty,x) { + var ret = 0; + if (leftx!=undefined && lefty!=undefined && rightx!=undefined && righty!=undefined && x!=undefined) { + if ((rightx-leftx) != 0) { + ret = lefty + (x-leftx)/(rightx-leftx)*(righty-lefty); + } else { + ret = (lefty+righty)/2; + } + } + return ret; + }, + correctPoints4Filltime: function(data,igraph,p0,cachetype) { + if ((data.filltime_start || data.filltime_end) && data.prefetch) { // if data points have been added at beginning and end, make them consistent with previous and next arrays if existing + if (cachetype == 'previous' && data.filltime_start) { + var p1 = data.pointsarray[igraph]; + if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { + p0[p0.length-1][1] = widget_chart.interpolate( + parseFloat(p0[p0.length-2][0]), + parseFloat(p0[p0.length-2][1]), + parseFloat(p1[1][0])+parseFloat(p0[p0.length-1][0]), // in fillmode this is the distance to the leftmost point + parseFloat(p1[1][1]), + parseFloat(p0[p0.length-1][0])); // in filltime mode this is the rightmost point + } + } + if (cachetype == 'next' && data.filltime_end) { + var p1 = data.pointsarray[igraph]; + if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { + p0[0][1] = widget_chart.interpolate( + parseFloat(p0[1][0]), + parseFloat(p0[1][1]), + parseFloat(p1[p1.length-2][0])-parseFloat(p1[p1.length-1][0]), // in fillmode this is the negative distance to the rightmost point + parseFloat(p1[p1.length-2][1]), + parseFloat(p0[0][0])); // in filltime mode this is the leftmost point + } + } + if (cachetype == undefined) { + if (data.filltime_start) { + var p1 = data.pointsarray_prev[igraph]; + if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { + p0[0][1] = widget_chart.interpolate( + parseFloat(p0[1][0]), + parseFloat(p0[1][1]), + parseFloat(p1[p1.length-2][0])-parseFloat(p1[p1.length-1][0]), // in fillmode this is the negative distance to the rightmost point + parseFloat(p1[p1.length-2][1]), + parseFloat(p0[0][0])); // in filltime mode this is the leftmost point + } + } + if (data.filltime_end) { + var p1 = data.pointsarray_next[igraph]; + if (p1 && p1.length && p1.length > 1 && p0 && p0.length && p0.length > 1) { + p0[p0.length-1][1] = widget_chart.interpolate( + parseFloat(p0[p0.length-2][0]), + parseFloat(p0[p0.length-2][1]), + parseFloat(p1[1][0])+parseFloat(p0[p0.length-1][0]), // in fillmode this is the distance to the leftmost point + parseFloat(p1[1][1]), + parseFloat(p0[p0.length-1][0])); // in filltime mode this is the rightmost point + } + } + } + } + }, + drawChart: function (elem,intype,swoffset,data_old,callback,cachetype) { // main function for generation of all HTML code and dynamics for graph called whenever thigs change (e.g. data update, shift, scale, ...) var theObj; if (elem) theObj=elem; else theObj=this; + $(theObj).data('drawing',true); var data = $(theObj).data(); + //console.log(cachetype==undefined?'actual':cachetype); + var data_save = jQuery.extend(true,{},$(theObj).data()); // keep original data in order to reset at end of 'previous' and 'next' calls + //if (cachetype && !data.baseDone) return; + var type = intype.split(' ')[0]; // derive the first word of type (second word sets reset flag) + var doReset = intype.split(' ')[1]?(intype.split(' ')[1]=='reset'):false; // derive the first word of type (second word sets reset flag) if (type=="resize") data.legend_pos = undefined; + //console.log('start --> ',cachetype, data.baseDone, pointsarray,new Error().stack); var y_margin = []; if ($.isArray(data.y_margin)) y_margin=[parseInt(data.y_margin[0]),parseInt(data.y_margin[data.y_margin.length-1])]; else y_margin=[parseInt(data.y_margin),parseInt(data.y_margin)]; @@ -2733,7 +3526,20 @@ var widget_chart = { data.noticks = noticks; data.leftOffset = 0; + doReset = doReset || type=='shift' || type=='scale' || data.offsetX===undefined || data.scaleX===undefined || data.scaleDeltaX===undefined; + if (doReset) { + data.offsetX = 0; // offset for shifting arbitrarily due to mousemove and touchmove handling + data.scaleX = 1; // scale for scaling arbitrarily due to mousemove and touchmove handling + data.scaleDeltaX = 0; // scale for scaling arbitrarily due to mousemove and touchmove handling + } + + if (cachetype=='next') { + data.shift -= 1; + } else if (cachetype=='previous') { + data.shift += 1; + } widget_chart.initializeTime(data); + //console.log(cachetype+": ",data.days_start, data.days_end, data.shift, data.scale, new Error().stack); var DDD = {}; if (!data.DDD) data.DDD = DDD; @@ -2763,7 +3569,7 @@ var widget_chart = { return ret+DDD.Width(n); }; - data.getGraphLeft = function() {var ret = this.noticks?this.leftOffset:this.leftOffset+this.textWidth_prim.sum(); return ret;}; + data.getGraphLeft = function() {var ret = this.noticks?this.leftOffset:this.leftOffset+(this.unusedYAxesVisible?this.textWidth_prim.sum():this.textWidth_prim.max()); return ret;}; data.transform = function (value,type,transfunc) { // do any kind of functional transformation of scaled y values in the original y data space var valData = (this.isPrimary(type))?(value+this.shiftY)/this.scaleY:(value+this.shiftY_sec)/this.scaleY_sec; @@ -2799,7 +3605,7 @@ var widget_chart = { } else { value = this[par+extension]; } - return value; + return $.isArray(value)?value[0]:value; }; data.getYAxisDisplayPrio = function(uxs,aindex) { @@ -2820,12 +3626,18 @@ var widget_chart = { return res; }; - if ($(theObj).parent().parent().data()) data.popup = ($(theObj).parent().parent().data().type == 'popup'); else data.popup = false; + data.getOffsetX = function(inv) {return this.offsetX + this.scaleDeltaX;}; + + data.popup = ($(theObj).parent().data().id && $(theObj).parent().data().id.match(/popup_.*/))?true:false; var instance = data.instance; var svg_old = $(theObj).find('svg.basesvg'+instance); // get previous graphics document (SVG, only skeleton at initial call) + + // unregister events for swipe + //if (!data.logProxy) widget_chart.detectSwipe(svg_old.find("rect.chart-background, [id*='graph-']"),true); + - if (!svg_old.parent().is(':visible') || svg_old.width()<=0) return; // chart div is not visible nothing to do + if (!svg_old.parent().is(':visible') || svg_old.width()<=0) {if (!cachetype) $(theObj).data('baseDone',true); return}; // chart div is not visible nothing to do if (svg_old.height() <= 0) { data.getDefaultSize($(theObj)); @@ -2837,27 +3649,30 @@ var widget_chart = { } var classesContainer = svg_old.find('#classesContainer'); - data.yLimits = []; - for (k=0; k'+ ' '+ ' '+ + ' '+ + ' '+ + ' '+ ' '+ ' '+ ' '+ @@ -3278,6 +4243,64 @@ var widget_chart = { ''+ ''+ ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ' '+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + 'Produces a 3D lighting effect.'+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ ''+ ''+ ''+ @@ -3307,7 +4330,7 @@ var widget_chart = { clip.left = data.getGraphLeft(); var zBack = (data.DDD.Setting[0] && data.DDD.Setting[0]<0)?data.DDD.BackplaneZ(data.DDD,data.nGraphs):0; var zFore = (data.DDD.Setting[0] && data.DDD.Setting[0]<0)?0:data.DDD.BackplaneZ(data.DDD,data.nGraphs); - clip.right = noticks?data.leftOffset+data.graphArea.width:data.leftOffset+data.textWidth_prim.sum()+data.graphArea.width/data.DDD.scaleX; + clip.right = noticks?data.leftOffset+data.graphArea.width:data.leftOffset+(data.unusedYAxesVisible?data.textWidth_prim.sum():data.textWidth_prim.max())+data.graphArea.width/data.DDD.scaleX; var p1 = widget_chart.getTransformedPoint(data,theObj,{x:0,y:data.graphHeight/100*data.baseheight,z:zBack}); var p2 = widget_chart.getTransformedPoint(data,theObj,{x:data.graphWidth/100*data.basewidth,y:data.graphHeight/100*data.baseheight,z:zBack}); clip.bottom = (Math.max(p1.y,p2.y)-data.DDD.shiftY)/data.DDD.scaleY; @@ -3319,7 +4342,11 @@ var widget_chart = { var svg_new = $( '' + (data.title?data.title_object:'') + '' + - '' + + '' + + ''+widget_chart.getClipPath(data,0,theObj,0)+widget_chart.getClipPath(data,0,theObj,0)+''+ + ''+widget_chart.getClipPath(data,0,theObj,3)+widget_chart.getClipPath(data,0,theObj,3)+''+ + ''+widget_chart.getClipPath(data,0,theObj,1)+widget_chart.getClipPath(data,0,theObj,1)+''+ + ''+widget_chart.getClipPath(data,0,theObj,2)+widget_chart.getClipPath(data,0,theObj,2)+''+ ''+ ''+ ''+ @@ -3327,13 +4354,8 @@ var widget_chart = { ''+ ''+ ''+ - '' + - ''+ - ''+ - ''+ - ''+ - '' + - ''+ + '' + + ''+ ''+ ''+ ''+ @@ -3356,7 +4378,7 @@ var widget_chart = { svg_new.find("rect.chart-background").attr(attrval); // test for functions on touch devices, currently not running yet - svg_new.find("rect.chart-background, [id*='graph-']").on("click", function(event) { + /*svg_new.find("rect.chart-background, [id*='graph-']").on("click", function(event) { }); svg_new.find("rect.chart-background, [id*='graph-']").on("swipeleft", function(event) { //$(event.delegateTarget).find("text.debug").text('Type: '+event.type+' X: '+event.pageX+' Y: '+event.pageY); @@ -3365,7 +4387,7 @@ var widget_chart = { svg_new.find("rect.chart-background, [id*='graph-']").on("swiperight", function(event) { //$(event.delegateTarget).find("text.debug").text('Type: '+event.type+' X: '+event.pageX+' Y: '+event.pageY); widget_chart.shift(event, $(event.delegateTarget),-1); - }); + });*/ var legend_container = widget_chart.drawLegend(data,theObj,style_array,fszC,classesContainer); @@ -3383,7 +4405,7 @@ var widget_chart = { // text element for show/hide of legend container var caption_text; if (!nobuttons) { - caption_text = widget_chart.createElem('text').attr({'class':'caption'+(data.showlegend?' active':' inactive'),'x':'49%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','style':'text-anchor:end'}); + caption_text = widget_chart.createElem('text').attr({'class':'caption legendbutton'+(data.showlegend?' active':' inactive'),'x':(noticks)?(data.timeranges!=''?7.7*fszB:6.2*fszB):(data.timeranges!=''?7.7*fszB:6.2*fszB)+'px','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','style':'text-anchor:end'}); caption_text.text("Legend"); legend_menu.append(caption_text); } @@ -3429,12 +4451,13 @@ var widget_chart = { for (var k=data.nGraphs-1; k>=0; k--) { // main loop for generation of page content (chart with graphs) uaxis = widget_chart.getArrayValue(uaxis_array,k,'primary'); AI = data.getAxisIndex(uaxis); - var unitsperpix = (data.yLimits[AI].primary.max-data.yLimits[AI].primary.min)/data.graphArea.height; // treat margin top and bottom if given if (data.isPrimary(uaxis) && !aiDone['primary'][AI]) { + var unitsperpix = (data.yLimits[AI].primary.max-data.yLimits[AI].primary.min)/data.graphArea.height; if (data.getAxisSetting('minvalue',uaxis)=="auto") data.yLimits[AI].primary.min -= y_margin[0]*unitsperpix; if (data.getAxisSetting('maxvalue',uaxis)=="auto") data.yLimits[AI].primary.max += y_margin[1]*unitsperpix; } else if (!aiDone['secondary'][AI]) { + var unitsperpix = (data.yLimits[AI].secondary.max-data.yLimits[AI].secondary.min)/data.graphArea.height; if (data.getAxisSetting('minvalue',uaxis)=="auto") data.yLimits[AI].secondary.min -= y_margin_sec[0]*unitsperpix; if (data.getAxisSetting('maxvalue',uaxis)=="auto") data.yLimits[AI].secondary.max += y_margin_sec[1]*unitsperpix; } @@ -3461,7 +4484,7 @@ var widget_chart = { widget_chart.scaleValues(pointsarray, k, data); var tstart = ftui.dateFromString(data.mindate); - style = widget_chart.getArrayValue(style_array,k,''); + style = widget_chart.getDynamicStyle(widget_chart.getArrayValue(style_array,k,'')); ptype = widget_chart.getArrayValue(ptype_array,k,'lines'); legend = widget_chart.getArrayValue(legend_array,k,'Graph '+k); @@ -3571,34 +4594,27 @@ var widget_chart = { points=pointsarray[k]; - if (ptype.search('icons:')>=0) { // copy data values to graphs which use ptype "icons:.." - var iv = ptype.split(':')[1]; - for (var i1=0, i1l=pointsarray[k].length; i1 pointsarray[k][i1][0]) { // found fitting reference value - pointsarray[k][i1][1] = pointsarray[iv][i2-1][1]; - found = true; - break; - } - } - if (!found) pointsarray[k][i1][1] = pointsarray[iv][i1][1]; // no fitting time value found, use last value of reference array instead - } - ptype = 'icons'; + //Setting the general attributes for different plot types + var fontFamily, fontWeight, symbol; + if (ptype.search('icons:')>=0) { + ptype = 'icons'; } else if (ptype.search(':')>=0) { ptype = ptype.split(':')[0]; } - - //Setting the general attributes for different plot types - var fontFamily, symbol; + if (ptype.indexOf('fa-')>=0 || ptype.indexOf('fs-')>=0 || ptype.indexOf('oa-')>=0) { //there seem to be font awesome symbols defined symbol = widget_chart.fontNameToUnicode(ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))); - fontFamily = (ptype.indexOf('fa-')>=0)?'FontAwesome':(ptype.indexOf('fs-')>=0)?'fhemSVG':'openautomation'; + fontFamily = (ptype.indexOf('fa-')>=0)?(ftui.version>'2.7.1'?'"Font Awesome 5 Free"':'FontAwesome'):(ptype.indexOf('fs-')>=0)?'fhemSVG':'openautomation'; + fontWeight = (ptype.indexOf('fa-')>=0)?(ftui.version>'2.7.1'?'900':''):''; ptype = 'symbol'; } + var attrval2; - switch (ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length))) { + var ptc = ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length)).split('-'); + var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; + var type = ptc[0]; + switch (type) { case 'lines': case 'steps': case 'fsteps': @@ -3608,13 +4624,13 @@ var widget_chart = { case 'cubic': case 'quadratic': case 'quadraticSmooth': - attrval={}; + attrval={'fill-rule':'evenodd'}; attrval.class = style; attrval.style = 'stroke-width: ' + strkG.stroke + 'px'; if (strkG.dash && strkG.dash!='none') {attrval.style = attrval.style + '; stroke-dasharray:' + strkG.dash;} // hack for behaviour of Firefox styleV = widget_chart.getStyleRuleValue(classesContainer, 'fill', '.'+style); - attrval.d = widget_chart.getSVGPoints(points, data, min, data.xrange, ptype, (styleV!='none')&&(!data.nofilldown[k]),uaxis); + attrval.d = widget_chart.getSVGPoints(points, data, min, data.xrange, ptype, (styleV!='none')&&(!nofilldown[k]),uaxis); if (styleV) {if(styleV.indexOf("url") >= 0) {attrval.style = attrval.style + '; fill: ' + styleV.slice(0,4)+styleV.slice(-(styleV.length-styleV.lastIndexOf("#"))).replace(/\"/g,'');}} if (ptype.indexOf('_proxy')>0) { // needed for text display in case of logproxy polar attrval2={}; @@ -3666,20 +4682,24 @@ var widget_chart = { if (!aiDone[data.flatUaxis(uaxis)][AI]) { svg.find('line').remove(); - var gridlines, gridlines_left, gridlines_bottom, buttons, tyaxis_prim, tyaxis_sec, txaxis, taxes; + var gridlines, gridlines_left, gridlines_bottom, buttons, tyaxis_prim, tyaxis_sec, txaxis, cxaxis, cgridlines, taxes; if (!gridlines) {gridlines = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!gridlines_left) {gridlines_left = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!gridlines_bottom) {gridlines_bottom = widget_chart.createElem('g').attr({'class':'gridlines','stroke':widget_chart.getStyleRuleValue(classesContainer, 'color', '')});} if (!buttons) {buttons = widget_chart.createElem('g').attr({'class':'buttons'});} - if (!tyaxis_prim[AI] && data.isPrimary(uaxis)) {tyaxis_prim[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_primary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX(-'+data.textWidth_prim.sum(0,AI-1)+'px); '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} - if (!tyaxis_sec[AI] && !data.isPrimary(uaxis)) {tyaxis_sec[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_secondary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX('+data.textWidth_sec.sum(0,AI-1)+'px); '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)});} + if (!tyaxis_prim[AI] && data.isPrimary(uaxis)) {tyaxis_prim[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_primary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX(-'+(data.unusedYAxesVisible?data.textWidth_prim.sum(0,AI-1):0)+'px); '+'opacity: '+(data.unusedYAxesVisible?'1':(AI==0?'1':'0'))+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} + if (!tyaxis_sec[AI] && !data.isPrimary(uaxis)) {tyaxis_sec[AI] = widget_chart.createElem('g').attr({'class':'text yaxis_secondary'+'-'+AI,'style':stringTransition+data.DDD.String.Rot+' translateX('+(data.unusedYAxesVisible?data.textWidth_sec.sum(0,AI-1):0)+'px); '+'opacity: '+(data.unusedYAxesVisible?'1':(AI==0?'1':'0'))+'; '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)});} if (!txaxis) {txaxis = widget_chart.createElem('g').attr({'class':'text xaxis','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)});} + if (!cxaxis) {cxaxis = widget_chart.createElem('g').attr({'style':data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRectXAxis'+data.instance+');'});} + if (!cgridlines) {cgridlines = widget_chart.createElem('g').attr({'style':data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+data.instance+');'});} if (!taxes) {taxes = widget_chart.createElem('g').attr({'class':'text axes'});} tyaxis = (data.isPrimary(uaxis))?tyaxis_prim[AI]:tyaxis_sec[AI]; taxes.append(tyaxis); - taxes.append(txaxis); + taxes.append(cxaxis); + cxaxis.append(txaxis); + gridlines.append(cgridlines); if (ptype.indexOf('_proxy')<0) { // only draw normal gridlines if not _proxy type //y-axis @@ -3787,9 +4807,8 @@ var widget_chart = { buttons.append(zoomMinus); if (data.timeranges != '') { - elem.data(data); var selTimes = widget_chart.createElem('text').attr({ - 'class':'buttons', + 'class':'buttons timeranges', 'x': (noticks)?(5*buttonWidth):(5*buttonWidth)+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -3802,7 +4821,7 @@ var widget_chart = { } var shiftMinus = widget_chart.createElem('text').attr({ - 'class':'buttons', + 'class':'buttons shiftminus', 'x': (noticks)?buttonWidth/2:buttonWidth/2+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -3810,12 +4829,16 @@ var widget_chart = { 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', // 'onclick':'widget_chart.shift(evt, $("svg.basesvg'+instance+'").parent(), 1)', }); - shiftMinus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), 1);}); // jshint ignore:line + shiftMinus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), 1, false, false, function() { + var baseobject = $("svg.basesvg"+instance).parent(); + var data = baseobject.data; + widget_chart.shiftXContent(baseobject,0,1,0,data); + });}); // jshint ignore:line shiftMinus.text(widget_chart.fontNameToUnicode('fa-arrow-circle-left')); buttons.append(shiftMinus); var shiftPlus = widget_chart.createElem('text').attr({ - 'class':'buttons', + 'class':'buttons shiftplus', 'x': (data.basewidth - ((noticks)?(buttonWidth/2):(buttonWidth/2)))+'px', 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', @@ -3823,7 +4846,11 @@ var widget_chart = { 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', // 'onclick':'widget_chart.shift(evt, $("svg.basesvg'+instance+'").parent(), -1)', }); - shiftPlus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), -1);}); // jshint ignore:line + shiftPlus.click(function(evt) {widget_chart.shift(evt, $("svg.basesvg"+instance).parent(), -1, false, false, function() { + var baseobject = $("svg.basesvg"+instance).parent(); + var data = baseobject.data; + widget_chart.shiftXContent(baseobject,0,1,0,data); + });}); // jshint ignore:line shiftPlus.text(widget_chart.fontNameToUnicode('fa-arrow-circle-right')); buttons.append(shiftPlus); @@ -3834,9 +4861,9 @@ var widget_chart = { 'y': fszT+data.margin+buttonWidth/2 + 'px', 'dy':'0.4em', 'text-anchor':'middle', - 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', + 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome' }); - rotX.text(widget_chart.fontNameToUnicode('fa-long-arrow-right')); + rotX.text(widget_chart.fontNameToUnicode('fa-long-arrow-'+(ftui.version > '2.7.1'?'alt-':'')+'right')); buttons.append(rotX); rotX.on('dblclick',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), -5, 0);}); // jshint ignore:line rotX.on('click',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 5, 0);}); // jshint ignore:line @@ -3865,7 +4892,7 @@ var widget_chart = { 'text-anchor':'middle', 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', }); - rotY.text(widget_chart.fontNameToUnicode('fa-long-arrow-up')); + rotY.text(widget_chart.fontNameToUnicode('fa-long-arrow-'+(ftui.version > '2.7.1'?'alt-':'')+'up')); buttons.append(rotY); rotY.on('dblclick',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 0, -5);}); // jshint ignore:line rotY.on('click',function(evt) {widget_chart.rotate(evt, $('svg.basesvg'+instance).parent(), 0, 5);}); // jshint ignore:line @@ -3879,7 +4906,7 @@ var widget_chart = { 'x': (data.basewidth - ((noticks)?(3.5*buttonWidth):(3.5*buttonWidth)))+'px', 'dy':'1.0em', 'text-anchor':'middle', - 'style':'font-family: FontAwesome', + 'style':ftui.version > '2.7.1'?'':'font-family: FontAwesome', }); rotY.text(widget_chart.fontNameToUnicode('fa-rotate-left')); gRotY.append(rotY); @@ -3909,6 +4936,7 @@ var widget_chart = { tyaxis.append(text); for (y=ymin_t; y<=max; y+=yticks ){ + if (yticks==0) break; fix = $.isArray(data.yLimits[AI].primary.yticks)?(data.yLimits[AI].primary.yticks[1]?(($.isArray(data.yLimits[AI].primary.yticks[1])?data.yLimits[AI].primary.yticks[1][0]:data.yLimits[AI].primary.yticks[1]) - ymin_t):ymin_t):widget_chart.precision( data.yLimits[AI].primary.yticks ); var line = widget_chart.createElem('line'); p1 = data.transD2W([0,y],uaxis); @@ -3952,6 +4980,19 @@ var widget_chart = { var ysc = (data.isPrimary(uaxis))?(y+data.yLimits[AI].primary.shiftY)/data.yLimits[AI].primary.scaleY:(y+data.yLimits[AI].secondary.shiftY)/data.yLimits[AI].secondary.scaleY; if (parseInt(ysc) == parseFloat(ysc.toFixed(5))) fix = 0; + if ($.isArray(ytary)) { + if (ytary[iyticks] && $.isArray(ytary[iyticks])) { + text.HTML2SVG(ytary[iyticks][1]); + //text.HTML2SVG( widget_chart.formatTicksText(ytary[iyticks][1],fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); + } else { + text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); + } + // exit for loop if yticks array is "finished" now + if(iyticks+1 >= ytary.length) break; + + yticks = $.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks]; + yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY); + /* if ($.isArray(ytary)) { yticks = (ytary.length && ytary.length > iyticks+1)?(($.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks])):yticks; yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY); @@ -3960,6 +5001,7 @@ var widget_chart = { } else { text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); } + */ } else { text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis))); // text.text( ((fix>-1 && fix<=20) ? parseFloat(ysc.toFixed(fix)) : ysc)+((uaxis=="secondary") ? unit_sec : unit) ); @@ -3998,28 +5040,34 @@ var widget_chart = { } else { textX1.HTML2SVG(tstart.ddmm()); } - txaxis.append(textX1); + if (!cachetype || xtext_offset!=0) txaxis.append(textX1); + textX1.click(function(evt) {widget_chart.resetTime(evt);}); var tx = new Date(tstart); - var moffset = tx.getMonth()*($.isArray(xticksArray)?xticksArray.length:12)/12; // care for array length for xticks setup + if (xticksArrayMonths) { + var moffset = tx.getMonth()*($.isArray(xticksArray)?xticksArray.length:12)/12; // care for array length for xticks setup + } else { + var moffset = 0; + } + x=0; var xold = 0; + var xlast = new Date(tstart); - for ( var xl=xticks; xl<=data.xrange; xl+=xticks ){ // counting up x values (in minutes) - + for ( var xl=(cachetype?0:xticks); xl<=data.xrange+(cachetype?0:0); xl+=xticks ){ // counting up x values (in minutes) tx = new Date(tstart); - var mindex = parseInt((xl/xticks+moffset-1)%($.isArray(xticksArray)?xticksArray.length:0)); - x = $.isArray(xticksArray)?(x+(xticksArray[mindex])*60*24):xl; - - if (data.xticks_round !== '') x = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart); - if (x>=data.xrange || x<=0) continue; // we have to care that nothing is written beyond end of chart - - tx.setMinutes(tstart.getMinutes() + x); - xtext_offset = widget_chart.getXTOffset(x,xold,tx,timeformat,data.xtext_offset); - xold = x; - + var mindex = Math.max(parseInt((xl/xticks+moffset-1)%($.isArray(xticksArray)?xticksArray.length:0)),0); + x = xl==0?0:($.isArray(xticksArray)?(x+(xticksArray[mindex])*60*24):xl); + var xc = x; + if (data.xticks_round !== '' && !$.isArray(xticksArray)) xc = widget_chart.roundXticks(data.xticks_round,x,data.xrange,tstart,((data.basewidth>200)?3.5:7)); + if (!cachetype && (xc>=data.xrange || xc<=0)) continue; // we have to care that nothing is written beyond end of chart + if (cachetype && (xc>data.xrange+xticks || xc<0)) continue; // we have to care that nothing is written beyond end of chart + + tx.setTime(tstart.getTime() + xc*60*1000); + xtext_offset = widget_chart.getXTOffset(xc,xold,tx,timeformat,data.xtext_offset); + xold = xc; var textX2 = widget_chart.createElem('text'); - posX = data.graphWidth*(x+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft(); + posX = data.graphWidth*(xc+(xtext_offset))/data.xrange*data.basewidth/100 + data.getGraphLeft(); posY = (((max))/(max-min)*data.graphHeight/100*data.baseheight+data.topOffset)+data.textHeight; textX2.attr({ 'class':'text axes xaxis', @@ -4042,24 +5090,28 @@ var widget_chart = { var textX2Value = (tx.hhmm()=="00:00"||xticks>1440) ? tx.ddmm() : tx.hhmm() ; // if we are at exactly 00:00 of if difference between ticks is larger than a day don't display hours. textX2.HTML2SVG(textX2Value); } - txaxis.append(textX2); + if (!cachetype || (cachetype && ((xc>0) && (xc0?ptype.indexOf('_proxy'):ptype.length))) { + var ptc = ptype.substring(0,Math.max(0,ptype.indexOf('_proxy')>0?ptype.indexOf('_proxy'):ptype.length)).split('-'); + var subtype = (ptc.length && ptc.length > 1)?ptc[1]:''; + var type = ptc[0]; + switch (type) { // add graphs themselves case 'lines': case 'steps': @@ -4169,7 +5227,7 @@ var widget_chart = { polyline.attr('style',polyline.attr('style')+'; opacity: 0.6'); for (i=depth, l=0; i>l; i-=1/dist) { if (i!==0) { - var svg_tmp = svgbase.clone().attr('style',data.DDD.String.Rot+'; '+data.DDD.String.Trans(i,k+1,data.DDD,data.xStrTO,data.yStrTO)); + var svg_tmp = svgbase.clone().attr('style',svgbase.attr('style')+'; '+data.DDD.String.Rot+'; '+data.DDD.String.Trans(i,k+1,data.DDD,data.xStrTO,data.yStrTO)); if (i!=depth && svg_tmp.find('path').attr('style')!==undefined) svg_tmp.find('path').attr('style',svg_tmp.find('path').attr('style').replace(/fill:.*;/,'fill:none; ')); if (i==depth) svg_tmp.find('path').attr('style',svg_tmp.find('path').attr('style')+'; opacity:0.6'); svg_tmp.find('path').attr('id',svg_tmp.find('path').attr('id')+'_'+i); @@ -4261,7 +5319,7 @@ var widget_chart = { g.attr('y0polar',data.transD2W([-data.minx,-data.yLimits[AI].primary.shiftY],'primary')[1]); //var strk = (g.css("stroke-width")) ? parseFloat(g.css("stroke-width").split('px')) : 1; - attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily; + attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily + ';font-weight:' + fontWeight; if (ptype == 'symbol') { for (j=0;j 3?points[j][3]:0; + var scl = points[j].length > 4?points[j][4]:1; + attrval.transform = "translate(" + attrval.x + " " + attrval.y + ") "+"rotate("+angl+")"+" scale("+scl+","+scl+") translate(" + (-attrval.x) + " " + (-attrval.y) + ")"; point_new.attr(attrval); point_new.text(symbol); g.append(point_new); @@ -4320,7 +5380,7 @@ var widget_chart = { svg_new.find("[class*=scaleyinvert]").each(function(index) {$(this).attr({'transform':'scale(1 -1)'});}); // generate crosshair container for cursor - var crosshair = widget_chart.createElem('g').attr({'class':'crosshair','pointer-events':'none','style':'overflow: inherit'}); + var crosshair = widget_chart.createElem('g').attr({'class':'crosshair container','pointer-events':'none','style':'overflow: inherit;'}); crosshair.append(widget_chart.createElem('line').attr({'class':'crosshair','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(0,0,data.DDD,data.xStrTO,data.yStrTO)})); if (data.DDD.Active) crosshair.append(widget_chart.createElem('line').attr({'class':'crosshair','style':data.DDD.String.Rot+'; '+data.DDD.String.Trans(data.DDD.Width(data.nGraphs-1),data.nGraphs,data.DDD,data.xStrTO,data.yStrTO)})); @@ -4340,7 +5400,8 @@ var widget_chart = { // text element for show/hide of crosshair cursor if (!nobuttons) { - var cursor_text = widget_chart.createElem('text').attr({'class':'caption'+((data.crosshair)?' active':' inactive'),'x':'51%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); + //var cursor_text = widget_chart.createElem('text').attr({'class':'caption'+((data.crosshair)?' active':' inactive'),'x':'51%','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); + var cursor_text = widget_chart.createElem('text').attr({'class':'caption cursorbutton'+((data.crosshair)?' active':' inactive'),'x':(noticks)?(data.timeranges!=''?8*fszB:6.5*fszB):(data.timeranges!=''?8*fszB:6.5*fszB)+'px','y':nobuttons?fszC/2+fszT+data.margin:Math.max(fszC,fszB)/2+fszT+data.margin,'dy':'0.4em','text-anchor':'begin'}); cursor_text.text("Cursor"); cursor_text.on('click', function(event) { if ($(event.delegateTarget).parents("[class^=basesvg]").parent().data('crosshair')) { @@ -4357,7 +5418,9 @@ var widget_chart = { legend_menu.append(cursor_text); } - // register events for crosshair cursor + // register events for crosshair cursor // register events for swipe + if (!data.logProxy) widget_chart.detectSwipe(svg_new.find("rect.chart-background, [id*='graph-']")); + svg_new.find("rect.chart-background, [id*='graph-']").on("mouseenter touchstart",function(event) { widget_chart.checkEvent(event); }); @@ -4373,15 +5436,98 @@ var widget_chart = { // Hack for problem in IE11 with transform of SVG elements browserCaps.doSVGTransformCorrection(svg_new); - // graph source is ready, add it to the page - svg_new.appendTo($(theObj)) + // graph source is ready, add it to the page if not in prefetch/cachemode + if (!cachetype) svg_new.appendTo($(theObj)) .css("width",data.width || data.defaultWidth) .css("height",data.height || data.defaultHeight); - + + // calculate and set the cliping rectangle for the x axis + if (!cachetype) { + var first_xtext = svg_new.find('g.text.xaxis').children().first(); + var cl_offset = (first_xtext&&first_xtext.length&&first_xtext.length>0)?first_xtext[0].getBoundingClientRect().width/2:0; + svg_new.find('[id="clipingRectXAxis'+data.instance+'"]').html(widget_chart.getClipPath(data,cl_offset,theObj,3)+widget_chart.getClipPath(data,-cl_offset,theObj,3)); + svg_new.find("svg.chart-primsec").attr("stlye",data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+(data.DDD.prefix=='-moz-'?'Graphs-':'Graphs-')+cachetype+data.instance+'); overflow: visible;'); + } + + if (cachetype) { // we are in prefetch/cache mode, do not use generated SVG graph but copy parts for display of previous and next timeframes when scrolling to main SVG + + var container = widget_chart.createElem('g'); + var offset = (cachetype=='previous'?(0-data.graphArea.width):(0+data.graphArea.width)); + var style; + container.attr('id','baseforDDD-'+cachetype); + //container.attr('style','overflow: inherit; z-index: '+(cachetype=='previous'?'100':'300')+'; '+data.DDD.prefix+'transform: '+data.DDD.String.Scale); + container.attr('style','overflow: inherit; z-index: '+(cachetype=='previous'?'100':'300')+';'+data.DDD.prefix+'transform: '+data.DDD.String.Scale+';'); + container.append(svg_new.find("[id^=cliping]").parent()); + container.find("[id=clipingRect"+data.instance+"]").attr('id','clipingRect-'+cachetype+data.instance); + container.find("[id=clipingRectXAxis"+data.instance+"]").attr('id','clipingRectXAxis-'+cachetype+data.instance); + container.find("[id=clipingRectGraphs"+data.instance+"]").attr('id','clipingRectGraphs-'+cachetype+data.instance); + container.find("[id=clipingRectCursor"+data.instance+"]").attr('id','clipingRectCursor-'+cachetype+data.instance); + style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRectXAxis-'+cachetype+data.instance+'); overflow: visible; ' + container.append(svg_new.find("g.text.xaxis").parent()); + container.find("g.text.xaxis").parent().attr('style',style); + style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect-'+cachetype+data.instance+'); overflow: visible; ' + container.append(svg_new.find("g.chart-gridlines")); + container.find('g.gridlines').attr('style',style); + container.find('line.yticks').remove(); + container.find('line.xaxis').remove(); + container.find('line.yaxis').remove(); + style = data.DDD.prefix.replace(/-moz-/g,'')+'clip-path: url(#clipingRect'+(data.DDD.prefix=='-moz-'?'Graphs-':'Graphs-')+cachetype+data.instance+'); overflow: visible;'; + container.append(svg_new.find("svg.chart-primsec").attr('style',style)); + //svg_new.find('g.lentries').appendTo(container); + svg_new.find('g.lentries').remove(); + cachetype == 'previous' ? + svg_old.find('rect.chart-background').parent().parent().append(container) : + svg_old.find('rect.chart-background').parent().parent().append(container); // needed because position in DOM decides on drawing sequence for SVGs + + var crosshair = svg_old.find('g.crosshair.container').remove(); + //crosshair.children().css('clip-path','url(#clipingRectCursor-'+cachetype+data.instance+')'); + svg_old.find('[id^=baseforDDD]').last().append(crosshair); // need to put cursor at the end of the DOM in order to have it painted on top + + widget_chart.shiftXContent(svg_old,doReset?0:data.offsetX,doReset?1:data.scaleX,doReset?0:data.scaleDeltaX,data); + + if (cachetype == 'previous') { + var xOffset = data.getGraphLeft(); + for (k=0, l=data.graphArea.width+xOffset; k max)) max = this[i]; + } + return max==-Infinity?0:max; + }; } + if (!Array.clone) { Array.prototype.clone = function (reverse) { var i, copy; @@ -4573,23 +5762,27 @@ function init_attr(elem) { // initialize all attributes called from widget init } }; + } // caluclation of min and max values for x axis from dates Date.prototype.isLeapYear = function(inyear) { var year = (inyear!==undefined)?inyear:this.getFullYear(); return (((year%4===0)&&(year%100!==0))||(year%400===0))?true:false; }; - Date.prototype.getDaysInMonth = function(inmonth) { + Date.prototype.myGetDaysInMonth = function(inmonth) { var month = (inmonth!==undefined)?inmonth:this.getMonth(); var year = this.getFullYear() + parseInt((month)/12); return [31,this.isLeapYear(year)?29:28,31,30,31,30,31,31,30,31,30,31][month%12]; }; + Date.prototype.getDateStringFHEM = function() { + return this.getFullYear()+'-'+(this.getMonth()+1).pad()+'-'+this.getDate().pad()+'T'+(this.getHours()-this.stdTimezoneOffset()/60).pad()+':'+this.getMinutes().pad()+':'+this.getSeconds().pad(); + }; Date.prototype.getDaysInMonthSum = function(inmonth) { var month = this.getMonth() var startmonth = (inmonth!==undefined)?(inmonth<=month?inmonth:0):0; var ret = 0; for(var i=startmonth; i<=month; i++) { - ret+=this.getDaysInMonth(i); + ret+=this.myGetDaysInMonth(i); } return ret; }; @@ -4709,7 +5902,7 @@ function init () { // initialization of widget, run at widget creation/reload }); this.defaultHeight = fullheight - siblingheights; } - this.defaultWidth = '93%'; + this.defaultWidth = '93%'; } data.getDefaultSize(elem); @@ -4734,6 +5927,10 @@ function init () { // initialization of widget, run at widget creation/reload var graphsshown_array = elem.data('graphsshown'); for (var k=0, ll=widget_chart.getnGraphs(elem.data()); k Date: Fri, 1 Apr 2022 08:09:50 +0200 Subject: [PATCH 3/3] Update widget_chart.js --- www/tablet/js/widget_chart.js | 85 ++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/www/tablet/js/widget_chart.js b/www/tablet/js/widget_chart.js index 706d0b01..1f570ebb 100644 --- a/www/tablet/js/widget_chart.js +++ b/www/tablet/js/widget_chart.js @@ -2,7 +2,7 @@ * Copyright (c) 2015-2017 Kurt Eckert * Under MIT License (http://www.opensource.org/licenses/mit-license.php) */ -/* Version 2.11.0 +/* Version 2.11.1 /* Compatible FTUI Version >= 2.7.2 /* global ftui:true, Modul_widget:true, Powerange:true */ @@ -717,12 +717,22 @@ var widget_chart = { } return {cx:cx, cy:cy}; }, - getYTicksBase: function(min,max) { // helper function for automatic calculation of yticks + getYTicksBase: function(min,max,max_yt_in) { // helper function for automatic calculation of yticks var ydiff=(max!=min)?max-min:(max>0)?max:1; + var max_yt = max_yt_in?max_yt_in:Infinity; + + var fact = 1; + ydiff *= fact; var p=parseInt(Math.log10(ydiff)); var yr = parseInt((ydiff)/Math.pow(10,p)+0.5); var yrt=[0.2, 0.4, 0.6, 1, 1, 1.5, 2, 2, 2, 2]; var yt = yrt[Math.max(0,yr-1)]*Math.pow(10,p); + while(ydiff/yt > max_yt) { + fact += 0.1; + p=parseInt(Math.log10(ydiff*fact)); + yr = parseInt((ydiff*fact)/Math.pow(10,p)+0.5); + yt = yrt[Math.max(0,yr-1)]*Math.pow(10,p); + } return yt; }, processLogproxyCorrection: function(bds,ptsin,style,scalex,scaley,elem) { // helper function for logproxy mode to take care of space for text @@ -1251,7 +1261,7 @@ var widget_chart = { }, getDynamicStyle: function(style) { var ret = ''; - if ($.isArray(style) && style[0].search(/graphbase/)>=0) { + if ($.isArray(style) && style[0].search && style[0].search(/graphbase/)>=0) { $.each(style, function(index, value) { if (value.search(/style/)>=0) ret = value.search(':')>=0?value.split(':')[1]:''; }); @@ -1274,11 +1284,11 @@ var widget_chart = { if (i>i_last) { // actual index is greater than previous one, append array if (actGr[slot] && actGr[slot].length > 0) mergepoints = [actGr[slot][actGr[slot].length-1],newGr[newGr.length-1]]; actGr[slot] = (i_last == -1)?newGr.clone():actGr[slot].concat(mergepoints).concat(newGr.clone(true)); - actGrStr[slot] = (!actGrStr[slot])?newGrStr.clone():actGrStr[slot].concat(newGrStr.clone(true)); + actGrStr[slot] = (i_last == -1)?newGrStr.clone():actGrStr[slot].concat(newGrStr.clone(true)); } else { // actual index is smaller than previous one, prepend array if (actGr[slot] && actGr[slot].length > 0) mergepoints = [newGr[newGr.length-1],actGr[slot][actGr[slot].length-1]]; actGr[slot] = (i_last == -1)?newGr.clone():newGr.concat(mergepoints).concat(actGr[slot].clone(true)); - actGrStr[slot] = (!actGrStr[slot])?newGrStr.clone():newGrStr.concat(actGrStr[slot].clone(true)); + actGrStr[slot] = (i_last == -1)?newGrStr.clone():newGrStr.concat(actGrStr[slot].clone(true)); } return i; @@ -2945,7 +2955,7 @@ var widget_chart = { 'x':data.legend_horiz?x+sumwidth+'px':((x+maxwidth))+'px', 'y':data.legend_horiz?((y+(fszC+5))+2.5)+'px':((y+(fszC+5)*(existingLegends.length-i))+2.5)+'px', 'igraph':$(existingLegends[i]).attr('igraph'), - 'opacity':(!data.graphsshown[existingLegends.length-i-1])?0.5:1 + 'opacity':(!data.graphsshown[i])?0.5:1 }); $(existingLegends[i]).off('click'); @@ -3597,7 +3607,7 @@ var widget_chart = { } }; - data.getAxisSetting = function(par,uaxis) { + data.getAxisSetting = function(par,uaxis,keeparray) { var extension = this.isPrimary(uaxis)?'':'_sec'; if ($.isArray(uaxis)) { var index = uaxis.length>1?uaxis[1]:0; @@ -3605,7 +3615,7 @@ var widget_chart = { } else { value = this[par+extension]; } - return $.isArray(value)?value[0]:value; + return ($.isArray(value) && !keeparray)?value[0]:value; }; data.getYAxisDisplayPrio = function(uxs,aindex) { @@ -3659,7 +3669,10 @@ var widget_chart = { if (!data.yLimits[AI]) data.yLimits[AI] = {primary:{},secondary:{}}; var minarray = data.getAxisSetting('minvalue',uaxis); var maxarray = data.getAxisSetting('maxvalue',uaxis); + var maxyticks = data.getAxisSetting('maxyticks',uaxis); + if (data.isPrimary(uaxis)) { + data.yLimits[AI].primary.maxyticks = maxyticks; data.yLimits[AI].primary.min = parseFloat( $.isArray(minarray) ? minarray[minarray.length-1] : (minarray!="auto") ? minarray : Number.POSITIVE_INFINITY ); data.yLimits[AI].primary.max = parseFloat( $.isArray(maxarray) ? maxarray[maxarray.length-1] : (maxarray!="auto") ? maxarray : Number.NEGATIVE_INFINITY ); if (data.isLogAxis(uaxis)) { @@ -3667,6 +3680,7 @@ var widget_chart = { data.yLimits[AI].primary.max = Math.log10_t(data.yLimits[AI].primary.max); } } else { + data.yLimits[AI].secondary.maxyticks = maxyticks; data.yLimits[AI].secondary.min = parseFloat( $.isArray(minarray) ? minarray[minarray.length-1] : (minarray!="auto") ? minarray : Number.POSITIVE_INFINITY ); data.yLimits[AI].secondary.max = parseFloat( $.isArray(maxarray) ? maxarray[maxarray.length-1] : (maxarray!="auto") ? maxarray : Number.NEGATIVE_INFINITY ); if (data.isLogAxis(uaxis)) { @@ -3761,8 +3775,8 @@ var widget_chart = { for (var k=data.nGraphs-1; k>=0; k--) { // main loop for generation of page content (chart with graphs) ptype = widget_chart.getArrayValue(ptype_array,k,'lines'); style = widget_chart.getArrayValue(style_array_prep,k,''); - if ((ptype.search('icons:')>=0) || ($.isArray(style) && style[0].search(/graphbase/)>=0)) { // copy data values to graphs which use ptype "icons:.." - if ($.isArray(style) && style[0].search(/graphbase/)>=0) { // there is a dynamic style definition + if ((ptype.search('icons:')>=0) || ($.isArray(style) && [0].search && style[0].search(/graphbase/)>=0)) { // copy data values to graphs which use ptype "icons:.." + if ($.isArray(style) && style[0].search && style[0].search(/graphbase/)>=0) { // there is a dynamic style definition $.each(["rotation","size"], function(index, value) { iv = -1; $.each(style, function(i,v){ @@ -3853,7 +3867,7 @@ var widget_chart = { points[i1][1] += pointsarray[iv][pointsarray[iv].length-1][1]; // add value of underlying graph to acutal value } } - if ((style.search(/fill/)>=0)) { + if ((style[0].search && style.search(/fill/)>=0)) { var lastPointUpper = points[points.length-2]?points[points.length-1].clone():[0,0]; points[points.length] = points[0]?points[0].clone():[0,0]; @@ -4015,24 +4029,24 @@ var widget_chart = { if (aiDone[AI]) continue; if (data.isPrimary(uaxis) && !aiDone.primary[AI]) { aiDone.primary[AI] = true; - data.yLimits[AI].primary.yticks = data.getAxisSetting('yticks',uaxis); + data.yLimits[AI].primary.yticks = data.getAxisSetting('yticks',uaxis,true); data.yLimits[AI].primary.yticks_format = data.getAxisSetting('yticks_format',uaxis); data.yLimits[AI].primary.yticks_prio = data.getYAxisDisplayPrio(data.flatUaxis(uaxis),AI); var yticks = parseFloat( (data.yLimits[AI].primary.yticks!="auto") ? data.yLimits[AI].primary.yticks : -1); var autoscaley = data.yLimits[AI].primary.yticks?data.yLimits[AI].primary.yticks=="auto":true; - if (autoscaley) fix = (widget_chart.getYTicksBase(data.yLimits[AI].primary.min,data.yLimits[AI].primary.max) < 10) ? 1 : 0; + if (autoscaley) fix = (widget_chart.getYTicksBase(data.yLimits[AI].primary.min,data.yLimits[AI].primary.max,data.yLimits[AI].primary.maxyticks) < 10) ? 1 : 0; var fix = $.isArray(data.yLimits[AI].primary.yticks)?(data.yLimits[AI].primary.yticks[1]?(($.isArray(data.yLimits[AI].primary.yticks[1])?data.yLimits[AI].primary.yticks[1][0]:data.yLimits[AI].primary.yticks[1]) - ymin_t):ymin_t):widget_chart.precision( data.yLimits[AI].primary.yticks ); var lytText = data.yLimits[AI].primary.yticks_format?data.yLimits[AI].primary.yticks_format.stripFormat().length:(data.yLimits[AI].primary.max==-Infinity)?3:data.yLimits[AI].primary.max.toFixed(fix).length; data.textWidth_prim[AI] = (foundPrimary&&!noticks)?widget_chart.getTextSizePixels(svg_old,str.repeat(lytText)+data.getAxisSetting('yunit',uaxis).stripFormat(),'text axes').width:0; data.textWidth_prim[AI] += ((noticks)?0:data.textHeight+2); // additional offset for axes descrption (text 90 deg) } else if (!data.isPrimary(uaxis) && !aiDone.secondary[AI]){ aiDone.secondary[AI] = true; - data.yLimits[AI].secondary.yticks = data.getAxisSetting('yticks',uaxis); + data.yLimits[AI].secondary.yticks = data.getAxisSetting('yticks',uaxis,true); data.yLimits[AI].secondary.yticks_format = data.getAxisSetting('yticks_format',uaxis); data.yLimits[AI].secondary.yticks_prio = data.getYAxisDisplayPrio(data.flatUaxis(uaxis),AI); var yticks = parseFloat( (data.yLimits[AI].secondary.yticks!="auto") ? data.yLimits[AI].secondary.yticks : -1); var autoscaley = data.yLimits[AI].secondary.yticks?data.yLimits[AI].secondary.yticks=="auto":true; - if (autoscaley) fix = (widget_chart.getYTicksBase(data.yLimits[AI].secondary.min,data.yLimits[AI].secondary.max) < 10) ? 1 : 0; + if (autoscaley) fix = (widget_chart.getYTicksBase(data.yLimits[AI].secondary.min,data.yLimits[AI].secondary.max,data.yLimits[AI].secondary.maxyticks) < 10) ? 1 : 0; var fix = $.isArray(data.yLimits[AI].secondary.yticks)?(data.yLimits[AI].secondary.yticks[1]?(($.isArray(data.yLimits[AI].secondary.yticks[1])?data.yLimits[AI].secondary.yticks[1][0]:data.yLimits[AI].secondary.yticks[1]) - ymin_t):ymin_t):widget_chart.precision( data.yLimits[AI].secondary.yticks ); var lytText = data.yLimits[AI].secondary.yticks_format?data.yLimits[AI].secondary.yticks_format.stripFormat().length:(data.yLimits[AI].secondary.max==-Infinity)?3:data.yLimits[AI].secondary.max.toFixed(fix).length; data.textWidth_sec[AI] = (foundSecondary&&!noticks)?widget_chart.getTextSizePixels(svg_old,str.repeat(lytText)+data.getAxisSetting('yunit',uaxis).stripFormat(),'text axes').width:0; @@ -4496,7 +4510,7 @@ var widget_chart = { if (data.isPrimary(uaxis)) { ytary = data.yLimits[AI].primary.yticks; if (data.yLimits[AI].primary.yticks?data.yLimits[AI].primary.yticks=="auto":true) { // check if autoscaling is set - yt = widget_chart.getYTicksBase(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.min):data.yLimits[AI].primary.min,data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.max):data.yLimits[AI].primary.max); + yt = widget_chart.getYTicksBase(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.min):data.yLimits[AI].primary.min,data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.max):data.yLimits[AI].primary.max,data.yLimits[AI].primary.maxyticks); ymin_t = (parseInt(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.min)/yt:data.yLimits[AI].primary.min/yt))*yt; if (ymin_t < (data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].primary.min):data.yLimits[AI].primary.min)) ymin_t+=yt; yticks = yt; @@ -4541,7 +4555,7 @@ var widget_chart = { } else { ytary = data.yLimits[AI].secondary.yticks; if (data.yLimits[AI].secondary.yticks?data.yLimits[AI].secondary.yticks=="auto":true) { // check if autoscaling is set - yt = widget_chart.getYTicksBase(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.min):data.yLimits[AI].secondary.min,data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.max):data.yLimits[AI].secondary.max); + yt = widget_chart.getYTicksBase(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.min):data.yLimits[AI].secondary.min,data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.max):data.yLimits[AI].secondary.max,data.yLimits[AI].secondary.maxyticks); ymin_t = (parseInt(data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.min)/yt:data.yLimits[AI].secondary.min/yt))*yt; if (ymin_t < (data.isLogAxis(uaxis)?Math.pow_t(10,data.yLimits[AI].secondary.min):data.yLimits[AI].secondary.min)) ymin_t+=yt; yticks = yt; @@ -4662,6 +4676,14 @@ var widget_chart = { attrval.style = 'stroke-width: ' + 0 + 'px' + ';fill: ' + styleV; attrval.min = min; break; + case 'values': + attrval={}; + styleV = widget_chart.getStyleRuleValue(classesContainer, 'stroke', '.'+style); + if (!styleV) {styleV = widget_chart.getStyleRuleValue(classesContainer, 'fill', '.'+style);} + var fs = widget_chart.getStyleRuleValue(classesContainer, 'font-size', '.'+style); + attrval.style = 'stroke-width: ' + 0 + 'px' + ';fill: ' + styleV + ';font-size:' + fs; + attrval.min = min; + break; } var svg = svg_new.find('svg.chart-primsec'); @@ -5303,6 +5325,7 @@ var widget_chart = { break; case 'symbol': case 'icons': + case 'values': g = widget_chart.createElem('g'); g.attr('class',style); g.attr('id',data.flatUaxis(uaxis) + "-graph-" + instance + "-" + k + "-" + ptype); @@ -5319,8 +5342,8 @@ var widget_chart = { g.attr('y0polar',data.transD2W([-data.minx,-data.yLimits[AI].primary.shiftY],'primary')[1]); //var strk = (g.css("stroke-width")) ? parseFloat(g.css("stroke-width").split('px')) : 1; - attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily + ';font-weight:' + fontWeight; if (ptype == 'symbol') { + attrval.style = attrval.style + ';font-size:' + strkG.stroke + 'px;' + 'text-anchor:middle' + ';font-family:' + fontFamily + ';font-weight:' + fontWeight; for (j=0;j 3?points[j][3]:0; + var scl = points[j].length > 4?points[j][4]:1; + attrval.transform = "translate(" + attrval.x + " " + attrval.y + ") "+"rotate("+angl+")"+" scale("+scl+","+scl+") translate(" + (-attrval.x) + " " + (-attrval.y) + ")"; + point_new.attr(attrval); + var yscale = (data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY; + var yshift = (data.isPrimary(uaxis))?data.yLimits[AI].primary.shiftY:data.yLimits[AI].secondary.shiftY; + var txt = points[j][2]?points[j][2]:parseFloat(((points[j][1]+yshift)/yscale).toFixed(data.cursor_digits)) + " " + (data.getAxisSetting('yunit',uaxis)); + point_new.text(txt); + g.append(point_new); + } } svg_chart.find('polyline').parent().append(g); break; @@ -5582,7 +5624,10 @@ var widget_chart = { data.done = true; data.baseDone = true; data.openDrawings -= 1; - if (data.openDrawings <= 0) data.drawing = false; // all outstanding drawings are done event handling for scale and shift can be reactivated + if (data.openDrawings <= 0) { + data.drawing = false; // all outstanding drawings are done event handling for scale and shift can be reactivated + if (!data.prefetch) data.runningRefresh = false; + } $(theObj).data(data); data_old = null;