def process(cls, widget, job, data): class ColInfo: def __init__(self, col, dataindex, istime=False): self.col = col self.key = cleankey(col.name) self.dataindex = dataindex self.istime = istime w_keys = [] # Widget column keys in order that matches data colinfo = {} # Map of ColInfo by key w_columns = [] # Widget column definitions for i, wc in enumerate(job.get_columns()): ci = ColInfo(wc, i, wc.datatype == 'time') colinfo[ci.key] = ci w_keys.append(ci.key) w_column = {'key': ci.key, 'label': wc.label, "sortable": True} if wc.datatype == 'bytes': w_column['formatter'] = 'formatBytes' elif wc.datatype == 'metric': w_column['formatter'] = 'formatMetric' elif wc.datatype == 'time': w_column['formatter'] = 'formatTime' elif wc.datatype == 'pct': w_column['formatter'] = 'formatPct' elif wc.datatype == 'html': w_column['allowHTML'] = True w_columns.append(w_column) rows = [] for rawrow in data: row = {} for i, key in enumerate(w_keys): if colinfo[key].istime: t = rawrow[i] try: val = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: val = t * 1000 else: val = rawrow[i] row[key] = val rows.append(row) data = { "chartTitle": widget.title.format(**job.actual_criteria), "columns": w_columns, "data": rows } return data
def process(cls, widget, job, data): class ColInfo: def __init__(self, col, dataindex, istime=False): self.col = col self.key = cleankey(col.name) self.dataindex = dataindex self.istime = istime w_keys = [] # Widget column keys in order that matches data colinfo = {} # Map of ColInfo by key w_columns = [] # Widget column definitions for i,wc in enumerate(job.get_columns()): ci = ColInfo(wc, i, wc.datatype == 'time') colinfo[ci.key] = ci w_keys.append(ci.key) w_column = {'key': ci.key, 'label': wc.label, "sortable": True} if wc.datatype == 'bytes': w_column['formatter'] = 'formatBytes' elif wc.datatype == 'metric': w_column['formatter'] = 'formatMetric' elif wc.datatype == 'time': w_column['formatter'] = 'formatTime' elif wc.datatype == 'pct': w_column['formatter'] = 'formatPct' elif wc.datatype == 'html': w_column['allowHTML'] = True w_columns.append(w_column) rows = [] for rawrow in data: row = {} for i, key in enumerate(w_keys): if colinfo[key].istime: t = rawrow[i] try: val = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: val = t * 1000 else: val = rawrow[i] row[key] = val rows.append(row) data = { "chartTitle": widget.title.format(**job.actual_criteria), "columns": w_columns, "data": rows } return data
def process(cls, widget, job, data): class ColInfo: def __init__(self, col, dataindex, istime=False): self.col = col self.dataindex = dataindex self.istime = istime colinfo = {} colnames = [] columns = [] for i, wc in enumerate(widget.table().get_columns()): colnames.append(wc.name) colinfo[wc.name] = ColInfo(wc, i, wc.datatype == 'time') column = {'key': wc.name, 'label': wc.label, "sortable": True} if wc.datatype == 'bytes': column['formatter'] = 'formatBytes' elif wc.datatype == 'metric': column['formatter'] = 'formatMetric' elif wc.datatype == 'time': column['formatter'] = 'formatTime' elif wc.datatype == 'pct': column['formatter'] = 'formatPct' elif wc.datatype == 'html': column['allowHTML'] = True columns.append(column) rows = [] for rawrow in data: row = {} for i, name in enumerate(colnames): if colinfo[name].istime: t = rawrow[i] try: val = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: val = t * 1000 else: val = rawrow[i] row[name] = val rows.append(row) data = { "chartTitle": widget.title.format(**job.actual_criteria), "columns": columns, "data": rows } return data
def process(cls, widget, job, data): class ColInfo: def __init__(self, col, dataindex, istime=False): self.col = col self.dataindex = dataindex self.istime = istime colinfo = {} colnames = [] columns = [] for i,wc in enumerate(widget.table().get_columns()): colnames.append(wc.name) colinfo[wc.name] = ColInfo(wc, i, wc.datatype == 'time') column = {'key': wc.name, 'label': wc.label, "sortable": True} if wc.datatype == 'bytes': column['formatter'] = 'formatBytes' elif wc.datatype == 'metric': column['formatter'] = 'formatMetric' elif wc.datatype == 'time': column['formatter'] = 'formatTime' elif wc.datatype == 'pct': column['formatter'] = 'formatPct' elif wc.datatype == 'html': column['allowHTML'] = True columns.append(column) rows = [] for rawrow in data: row = {} for i, name in enumerate(colnames): if colinfo[name].istime: t = rawrow[i] try: val = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: val = t * 1000 else: val = rawrow[i] row[name] = val rows.append(row) data = { "chartTitle": widget.title.format(**job.actual_criteria), "columns": columns, "data": rows } return data
def parse_data(self): """ Reformat shark data results to be uniform tabular format """ out = [] if self.timeseries: # use sample times for each row for d in self.data: t = timeutils.datetime_to_microseconds(d['t']) / float(10 ** 6) out.extend([t] + x for x in d['vals']) else: for d in self.data: out.extend(x for x in d['vals']) self.data = out
def parse_data(self): """ Reformat shark data results to be uniform tabular format """ out = [] if self.timeseries: # use sample times for each row for d in self.data: if d['t'] is not None: t = timeutils.datetime_to_microseconds(d['t']) / float(10** 6) out.extend([t] + x for x in d['vals']) else: for d in self.data: out.extend(x for x in d['vals']) self.data = out
def process(cls, widget, data): qcols = [] columns = [] for wc in widget.table().get_columns(): qcols.append(wc.name) column = {'key': wc.name, 'label': wc.label, "sortable": True} if wc.datatype == 'bytes': column['formatter'] = 'formatBytes' elif wc.datatype == 'metric': column['formatter'] = 'formatMetric' elif wc.datatype == 'time': column['formatter'] = 'formatTime' elif wc.datatype == 'pct': column['formatter'] = 'formatPct' elif wc.datatype == 'html': column['allowHTML'] = True columns.append(column) rows = [] for reportrow in data: row = {} for i in range(0, len(qcols)): if qcols[i] == 'time': t = reportrow[i] try: val = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: val = t * 1000 else: val = reportrow[i] row[qcols[i]] = val i = i + 1 rows.append(row) data = { "chartTitle": widget.title, "columns": columns, "data": rows } return data
def process(cls, widget, job, data): class ColInfo: def __init__(self, col, dataindex, axis, istime=False): self.col = col self.key = cleankey(col.name) self.dataindex = dataindex self.axis = axis self.istime = istime t_cols = job.get_columns() colinfo = {} # map by widget key # columns of '*' is a special case, just use all # defined columns other than time if widget.options.columns == '*': valuecolnames = [ col.name for col in t_cols if col.datatype != 'time' ] else: valuecolnames = widget.options.columns # Column keys are the 'cleaned' column names w_keys = [cleankey(n) for n in valuecolnames] # Retrieve the desired value columns # ...and the indices for the value values # (as the 'data' has *all* columns) for i, c in enumerate(t_cols): if c.datatype == 'time': ci = ColInfo(c, i, -1, istime=True) elif c.name in valuecolnames: ci = ColInfo(c, i, -1, istime=False) colinfo[ci.key] = ci w_series = [] axes = Axes(widget.options.axes) # Setup the time axis w_axes = { "time": { "keys": ["time"], "position": "bottom", "type": "time", "styles": { "label": { "fontSize": "8pt", "rotation": "-45" } } } } # Create a better time format depending on t0/t1 t_dataindex = colinfo['time'].dataindex t0 = data[0][t_dataindex] t1 = data[-1][t_dataindex] if not hasattr(t0, 'utcfromtimestamp'): t0 = datetime.datetime.fromtimestamp(t0) t1 = datetime.datetime.fromtimestamp(t1) if (t1 - t0).seconds < 2: w_axes['time']['formatter'] = 'formatTimeMs' elif (t1 - t0).seconds < 120: w_axes['time']['labelFormat'] = '%k:%M:%S' else: w_axes['time']['labelFormat'] = '%k:%M' # Setup the other axes, checking the axis for each column for w_key in w_keys: # Need to interate the valuecolnames array to preserve order ci = colinfo[w_key] w_series.append({ "xKey": "time", "xDisplayName": "Time", "yKey": ci.key, "yDisplayName": ci.col.label, "styles": { "line": { "weight": 1 }, "marker": { "height": 3, "width": 3 } } }) ci.axis = axes.getaxis(ci.col.name) axis_name = 'axis' + str(ci.axis) if axis_name not in w_axes: w_axes[axis_name] = { "type": "numeric", "position": axes.position(ci.axis), "keys": [] } w_axes[axis_name]['keys'].append(ci.key) # Output row data rows = [] # min/max values by axis 0/1 minval = {} maxval = {} stacked = widget.options.stacked # Iterate through all rows if input data for rawrow in data: t = rawrow[t_dataindex] try: t = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: t = t * 1000 row = {'time': t} rowmin = {} rowmax = {} for ci in colinfo.values(): if ci.istime: continue a = ci.axis val = rawrow[ci.dataindex] row[ci.key] = val if val != '' else None if a not in rowmin: rowmin[a] = val if val != '' else 0 rowmax[a] = val if val != '' else 0 else: rowmin[a] = (rowmin[a] + val) if stacked else min(rowmin[a], val) rowmax[a] = (rowmax[a] + val) if stacked else max(rowmax[a], val) for a in rowmin.keys(): minval[a] = rowmin[a] if (a not in minval) else min( minval[a], rowmin[a]) maxval[a] = rowmax[a] if (a not in maxval) else max( maxval[a], rowmax[a]) rows.append(row) # Setup the scale values for the axes for ci in colinfo.values(): if ci.istime: continue axis_name = 'axis' + str(ci.axis) if minval and maxval: n = NiceScale(minval[ci.axis], maxval[ci.axis]) w_axes[axis_name]['minimum'] = "%.10f" % n.niceMin w_axes[axis_name]['maximum'] = "%.10f" % n.niceMax w_axes[axis_name]['tickExponent'] = math.log10(n.tickSpacing) w_axes[axis_name]['styles'] = { 'majorUnit': { 'count': n.numTicks } } else: # empty data which would result in keyError above w_axes[axis_name]['minimum'] = "0" w_axes[axis_name]['maximum'] = "1" w_axes[axis_name]['tickExponent'] = 1 w_axes[axis_name]['styles'] = {'majorUnit': {'count': 1}} if ci.col.datatype == 'bytes': w_axes[axis_name]['formatter'] = 'formatBytes' elif ci.col.datatype == 'metric': w_axes[axis_name]['formatter'] = 'formatMetric' data = { "chartTitle": widget.title.format(**job.actual_criteria), "type": "area" if stacked else "combo", "stacked": stacked, "dataProvider": rows, "seriesCollection": w_series, "axes": w_axes, "legend": { "position": "bottom", "fontSize": "8pt", "styles": { "gap": 0 } }, "interactionType": "planar" if stacked else "marker" } #logger.debug("data:\n\n%s\n" % data) return data
def process(cls, widget, data): class ColInfo: def __init__(self, col, dataindex, axis, istime=False): self.col = col self.dataindex = dataindex self.axis = axis self.istime = istime t_cols = widget.table().get_columns() colinfo = {} if widget.options.columns == '*': valuecolnames = [col.name for col in t_cols if col.datatype != 'time'] else: valuecolnames = widget.options.columns # Retrieve the desired value columns # ...and the indices for the value values (as the 'data' has *all* columns) for i, c in enumerate(t_cols): if c.datatype == 'time': colinfo['time'] = ColInfo(c, i, -1, istime=(c.datatype == 'time')) elif c.name in valuecolnames: colinfo[c.name] = ColInfo(c, i, -1, istime=(c.datatype == 'time')) series = [] w_axes = Axes(widget.options.axes) # Create a better time format depending on t0/t1 t_dataindex = colinfo['time'].dataindex #print ("t_dataindex: %d, data[0]: %s, data[1]: %s" % (t_dataindex, str(data[0]), str(data[1]))) t0 = data[0][t_dataindex] t1 = data[-1][t_dataindex] if not hasattr(t0, 'utcfromtimestamp'): t0 = datetime.datetime.fromtimestamp(t0) t1 = datetime.datetime.fromtimestamp(t1) # Setup the time axis axes = {"time": {"keys": ["time"], "position": "bottom", "type": "time", "labelFormat": "%k:%M", "styles": {"label": {"fontSize": "8pt"}}}} # Setup the other axes, checking the axis for each column for colname in valuecolnames: # Need to interate the valuecolnames array to preserve order ci = colinfo[colname] series.append({"xKey": "time", "xDisplayName": "Time", "yKey": ci.col.name, "yDisplayName": ci.col.label, "styles": {"line": {"weight": 1}, "marker": {"height": 3, "width": 3}}}) ci.axis = w_axes.getaxis(ci.col.name) axis_name = 'axis' + str(ci.axis) if axis_name not in axes: axes[axis_name] = {"type": "numeric", "position": w_axes.position(ci.axis), "keys": [] } axes[axis_name]['keys'].append(ci.col.name) # Output row data rows = [] # min/max values by axis 0/1 minval = {} maxval = {} stacked = widget.options.stacked # Iterate through all rows if input data for reportrow in data: t = reportrow[t_dataindex] try: t = timeutils.datetime_to_microseconds(t) / 1000 except AttributeError: t = t * 1000 row = {'time': t} rowmin = {} rowmax = {} for ci in colinfo.values(): if ci.istime: continue a = ci.axis val = reportrow[ci.dataindex] row[ci.col.name] = val if val != '' else None if a not in rowmin: rowmin[a] = val if val != '' else 0 rowmax[a] = val if val != '' else 0 else: rowmin[a] = (rowmin[a] + val) if stacked else min(rowmin[a], val) rowmax[a] = (rowmax[a] + val) if stacked else max(rowmax[a], val) for a in rowmin.keys(): minval[a] = rowmin[a] if (a not in minval) else min(minval[a], rowmin[a]) maxval[a] = rowmax[a] if (a not in maxval) else max(maxval[a], rowmax[a]) rows.append(row) # Setup the scale values for the axes for ci in colinfo.values(): if ci.istime: continue axis_name = 'axis' + str(ci.axis) if minval and maxval: n = NiceScale(minval[ci.axis], maxval[ci.axis]) axes[axis_name]['minimum'] = "%.10f" % n.niceMin axes[axis_name]['maximum'] = "%.10f" % n.niceMax axes[axis_name]['tickExponent'] = math.log10(n.tickSpacing) axes[axis_name]['styles'] = {'majorUnit': {'count': n.numTicks}} else: # empty data which would result in keyError above axes[axis_name]['minimum'] = "0" axes[axis_name]['maximum'] = "1" axes[axis_name]['tickExponent'] = 1 axes[axis_name]['styles'] = {'majorUnit': {'count': 1}} if ci.col.datatype == 'bytes': axes[axis_name]['formatter'] = 'formatBytes' elif ci.col.datatype == 'metric': axes[axis_name]['formatter'] = 'formatMetric' data = { "chartTitle": widget.title, "type": "area" if stacked else "combo", "stacked": stacked, "dataProvider": rows, "seriesCollection": series, "axes": axes, "legend": {"position": "bottom", "fontSize": "8pt", "styles": {"gap": 0}}, "interactionType": "planar" if stacked else "marker" } #logger.debug("data:\n\n%s\n" % data) return data