- modified chartjs for better zoom on touchpad - flexible number of charts - handle bool as checkbox - handle enum as select (pull down menu) - disable swiper where not needed and many more
172 lines
7.8 KiB
Python
172 lines
7.8 KiB
Python
import time
|
|
import sys
|
|
if sys.version_info >= (3,6):
|
|
Dict = dict
|
|
else:
|
|
from collections import OrderedDict as Dict
|
|
|
|
|
|
class PrettyFloat(float):
|
|
def __repr__(self):
|
|
return '%.15g' % self
|
|
|
|
|
|
def get_abs_time(*times):
|
|
now = int(time.time() + 0.999)
|
|
oneyear = 365 * 24 * 3600
|
|
return tuple(t + now if t < oneyear else t for t in times)
|
|
|
|
|
|
class ColorMap(object):
|
|
""""
|
|
ColorMap is using official CSS color names, with the exception of Green, as this
|
|
is defined differently with X11 colors than in SEA, and used heavily in config files.
|
|
Here Green is an alias to Lime (#00FF00) and MidGreen is #008000, which is called Green in CSS.
|
|
The function to_code is case insensitive and accepts also names with underscores.
|
|
The order is choosen by M. Zolliker for the SEA client, originally only the first 16 were used.
|
|
"""
|
|
hex_name = (
|
|
("#FFFFFF", "White"), ("#FF0000", "Red"), ("#00FF00", "Lime"), ("#0000FF", "Blue"), ("#FF00FF", "Magenta"),
|
|
("#FFFF00", "Yellow"), ("#00FFFF", "Cyan"), ("#000000", "Black"), ("#FFA500", "Orange"),
|
|
("#006400", "DarkGreen"), ("#9400D3", "DarkViolet"), ("#A52A2A", "Brown"), ("#87CEEB", "SkyBlue"),
|
|
("#808080", "Gray"), ("#FF69B4", "HotPink"), ("#FFFFE0", "LightYellow"), ("#00FF7F", "SpringGreen"),
|
|
("#000080", "Navy"), ("#1E90FF", "DodgerBlue"), ("#9ACD32", "YellowGreen"), ("#008B8B", "DarkCyan"),
|
|
("#808000", "Olive"), ("#DEB887", "BurlyWood"),
|
|
("#7B68EE", "MediumSlateBlue"), ("#483D8B", "DarkSlateBlue"), ("#98FB98", "PaleGreen"), ("#FF1493", "DeepPink"),
|
|
("#FF6347", "Tomato"), ("#32CD32", "LimeGreen"), ("#DDA0DD", "Plum"), ("#7FFF00", "Chartreuse"),
|
|
("#800080", "Purple"), ("#00CED1", "DarkTurquoise"), ("#8FBC8F", "DarkSeaGreen"), ("#4682B4", "SteelBlue"),
|
|
("#800000", "Maroon"),
|
|
("#3CB371", "MediumSeaGreen"), ("#FF4500", "OrangeRed"), ("#BA55D3", "MediumOrchid"),
|
|
("#2F4F4F", "DarkSlateGray"), ("#CD853F", "Peru"), ("#228B22", "ForestGreen"), ("#48D1CC", "MediumTurquoise"),
|
|
("#DC143C", "Crimson"),
|
|
("#D3D3D3", "LightGray"), ("#ADFF2F", "GreenYellow"), ("#7FFFD4", "Aquamarine"), ("#BC8F8F", "RosyBrown"),
|
|
("#20B2AA", "LightSeaGreen"), ("#C71585", "MediumVioletRed"), ("#F0E68C", "Khaki"),
|
|
("#6495ED", "CornflowerBlue"),
|
|
("#556B2F", "DarkOliveGreen"), ("#CD5C5C", "IndianRed "), ("#2E8B57", "SeaGreen"), ("#F08080", "LightCoral"),
|
|
("#8A2BE2", "BlueViolet"), ("#AFEEEE", "PaleTurquoise"), ("#4169E1", "RoyalBlue"), ("#0000CD", "MediumBlue"),
|
|
("#B8860B", "DarkGoldenRod"), ("#00BFFF", "DeepSkyBlue"), ("#FFC0CB", "Pink"), ("#4B0082", "Indigo "),
|
|
("#A0522D", "Sienna"),
|
|
("#FFD700", "Gold"), ("#F4A460", "SandyBrown"), ("#DAA520", "GoldenRod"), ("#DA70D6", "Orchid"),
|
|
("#E6E6FA", "Lavender"),
|
|
("#5F9EA0", "CadetBlue"), ("#D2691E", "Chocolate"), ("#66CDAA", "MediumAquaMarine"), ("#6B8E23", "OliveDrab"),
|
|
("#A9A9A9", "DarkGray"), ("#BDB76B", "DarkKhaki"), ("#696969", "DimGray"), ("#B0C4DE", "LightSteelBlue"),
|
|
("#191970", "MidnightBlue"), ("#FFE4C4", "Bisque"), ("#6A5ACD", "SlateBlue"), ("#EE82EE", "Violet"),
|
|
("#8B4513", "SaddleBrown"), ("#FF7F50", "Coral"), ("#008000", "MidGreen"), ("#DB7093", "PaleVioletRed"),
|
|
("#C0C0C0", "Silver"),
|
|
("#E0FFFF", "LightCyan"), ("#9370DB", "MediumPurple"), ("#FF8C00", "DarkOrange"),
|
|
("#00FA9A", "MediumSpringGreen"),
|
|
("#E9967A", "DarkSalmon"), ("#778899", "LightSlateGray"), ("#9932CC", "DarkOrchid"),
|
|
("#EEE8AA", "PaleGoldenRod"),
|
|
("#F8F8FF", "GhostWhite"), ("#FFA07A", "LightSalmon"), ("#ADD8E6", "LightBlue"), ("#D8BFD8", "Thistle"),
|
|
("#FFE4E1", "MistyRose"), ("#FFDEAD", "NavajoWhite"), ("#40E0D0", "Turquoise"), ("#90EE90", "LightGreen"),
|
|
("#B22222", "FireBrick"), ("#008080", "Teal"), ("#F0FFF0", "HoneyDew"), ("#FFFACD", "LemonChiffon"),
|
|
("#FFF5EE", "SeaShell"),
|
|
("#F5F5DC", "Beige"), ("#DCDCDC", "Gainsboro"), ("#FA8072", "Salmon"), ("#8B008B", "DarkMagenta"),
|
|
("#FFB6C1", "LightPink"),
|
|
("#708090", "SlateGray"), ("#87CEFA", "LightSkyBlue"), ("#FFEFD5", "PapayaWhip"), ("#D2B48C", "Tan"),
|
|
("#FFFFF0", "Ivory"),
|
|
("#F0FFFF", "Azure"), ("#F5DEB3", "Wheat"), ("#00008B", "DarkBlue"), ("#FFDAB9", "PeachPuff"),
|
|
("#8B0000", "DarkRed"),
|
|
("#FAF0E6", "Linen"), ("#B0E0E6", "PowderBlue"), ("#FFE4B5", "Moccasin"), ("#F5F5F5", "WhiteSmoke"),
|
|
("#FFF8DC", "Cornsilk"),
|
|
("#FFFAFA", "Snow"), ("#FFF0F5", "LavenderBlush"), ("#FFEBCD", "BlanchedAlmond"), ("#F0F8FF", "AliceBlue"),
|
|
("#FAEBD7", "AntiqueWhite"), ("#FDF5E6", "OldLace"), ("#FAFAD2", "LightGoldenRodYellow"),
|
|
("#F5FFFA", "MintCream"),
|
|
("#FFFAF0", "FloralWhite"), ("#7CFC00", "LawnGreen"), ("#663399", "RebeccaPurple"))
|
|
codes = {}
|
|
for i, pair in enumerate(hex_name):
|
|
codes[pair[0]] = i
|
|
low = pair[1].lower()
|
|
codes[low] = i
|
|
codes[low.replace("gray", "grey")] = i
|
|
codes["green"] = 2
|
|
codes["fuchsia"] = 4
|
|
codes["aqua"] = 6
|
|
|
|
@staticmethod
|
|
def to_code(colortext):
|
|
try:
|
|
return int(colortext)
|
|
except ValueError:
|
|
return ColorMap.codes.get(colortext.lower().replace("_", ""),-1)
|
|
|
|
@staticmethod
|
|
def check_hex(code):
|
|
if not code.startswith("#"):
|
|
return None
|
|
if len(code) == 4: # convert short code to long code
|
|
code = code[0:2] + code[1:3] + code[2:4] + code[3]
|
|
if len(code) != 7:
|
|
return None
|
|
try:
|
|
int(code[1:]) # we have a valid hex color code
|
|
return code
|
|
except ValueError:
|
|
return None
|
|
|
|
@staticmethod
|
|
def to_hex(code):
|
|
try:
|
|
return ColorMap.hex_name[code][0]
|
|
except IndexError:
|
|
return -1
|
|
|
|
|
|
def get_vars(main, time):
|
|
result = {}
|
|
|
|
time, = get_abs_time(time)
|
|
# get last value only
|
|
curves = main.get_curve_options((time, time))
|
|
for key, opts in curves.items():
|
|
if not opts.get('show', False):
|
|
continue
|
|
print(key, opts)
|
|
opts = dict(name=key, **opts)
|
|
unit = opts.pop('unit', '*')
|
|
tag = opts.pop('tag', unit)
|
|
if not tag in result:
|
|
result[tag] = dict(tag=tag, unit=unit, curves=Dict())
|
|
if 'label' not in opts:
|
|
opts['label'] = opts['name']
|
|
result[tag]["curves"][key] = opts
|
|
|
|
# determine colors
|
|
for _, curvegroup in result.items():
|
|
color_set = set()
|
|
auto_curves = []
|
|
curve_list = list(curvegroup["curves"].values())
|
|
curvegroup['curves'] = curve_list
|
|
for curve in curve_list:
|
|
col = curve.get("color", '').strip()
|
|
c = ColorMap.to_code(col)
|
|
if c < 0:
|
|
valid = ColorMap.check_hex(col)
|
|
if valid:
|
|
curve["original_color"] = col
|
|
curve["color"] = valid
|
|
else:
|
|
auto_curves.append(curve)
|
|
curve["original_color"] = col + "?"
|
|
else:
|
|
color_set.add(c)
|
|
curve["original_color"] = col
|
|
curve["color"] = ColorMap.to_hex(c)
|
|
c = 1 # omit white
|
|
for curve in auto_curves:
|
|
while c in color_set:
|
|
c += 1 # find unused color
|
|
curve["color"] = ColorMap.to_hex(c)
|
|
c += 1
|
|
return result
|
|
|
|
|
|
def get_curves(main, keys, timerange, cut_begin=True):
|
|
curves = main.get_curves(keys, get_abs_time(*timerange), maxpoints=500, cut_begin=cut_begin)
|
|
opts = main.get_curve_options(timerange, keys)
|
|
#if 'tt:target' in curves:
|
|
# print('---')
|
|
# print(curves['tt:target'].fmtm())
|
|
# print('TT', curves['tt:target'].for_json()[-5:])
|
|
return {k: c.for_json(opts.get(k, {}).get('period', 0)) for k, c in curves.items()}
|