Fixed charts
diff --git a/chart/__init__.py b/chart/__init__.py
index e69de29..91f24c6 100644
--- a/chart/__init__.py
+++ b/chart/__init__.py
@@ -0,0 +1,9 @@
+# Patch MARKER constant
+
+import sys
+from GChartWrapper import constants
+import GChartWrapper.GChart
+
+constants.MARKERS += 'E'
+print sys.modules['GChartWrapper.GChart']
+sys.modules['GChartWrapper.GChart'].MARKERS += 'E'
diff --git a/chart/charts.py b/chart/charts.py
index f985526..549b820 100644
--- a/chart/charts.py
+++ b/chart/charts.py
@@ -19,7 +19,9 @@
     t.start()
 
 
-def render_vertical_bar(title, legend, dataset, width=700, height=400,
+def render_vertical_bar(title, legend, bars_data, bars_dev_top,
+                        bars_dev_bottom,
+                        width=700, height=400,
                         scale_x=None, scale_y=None, label_x=None,
                         label_y=None, lines=()):
     """
@@ -57,49 +59,37 @@
     bar = VerticalBarGroup([], encoding='text')
     bar.title(title)
 
-    values = []
-    deviations = []
+    dataset = bars_data + bars_dev_top + bars_dev_bottom + [lines[0][0]]
 
-    for d in dataset:
-        val, dev = zip(*d)
-
-        display_dev = []
-        for i in range(len(val)):
-            display_dev.append((val[i]-dev[i], val[i]+dev[i]))
-        values.append(val)
-        # deviations.extend(zip(*dev))
-        deviations.extend(zip(*display_dev))
-
-    # bar.dataset(values + deviations, series=len(values))
-    bar.dataset(values + deviations + [l[0] for l in lines],
-                series=len(values))
+    bar.dataset(dataset, series=len(bars_data))
     bar.axes.type('xyy')
     bar.axes.label(2, None, label_x)
     if scale_x:
         bar.axes.label(0, *scale_x)
 
-    max_value = (max([max(l) for l in values + deviations + [lines[1][0]]]))
+    max_value = (max([max(l) for l in dataset[:2]]))
     bar.axes.range(1, 0, max_value)
     bar.axes.style(1, 'N*s*')
     bar.axes.style(2, '000000', '13')
 
-    bar.scale(*[0, max_value] * len(values + deviations))
+    bar.scale(*[0, max_value] * 3)
 
     bar.bar('r', '.1', '1')
     for i in range(1):
-        bar.marker('E', '000000', '%s:%s' % ((len(values) + i*2), i),
+        bar.marker('E', '000000', '%s:%s' % ((len(bars_data) + i*2), i),
                    '', '1:10')
     bar.color(*COLORS)
     bar.size(width, height)
 
     axes_type = "xyy"
 
-    scale = [0, max_value] * len(values + deviations)
+    scale = [0, max_value] * len(bars_dev_top + bars_dev_bottom + bars_data)
     if lines:
         line_n = 0
         for data, label, axe, leg in lines:
-            bar.marker('D', COLORS[len(values) + line_n],
-                       (len(values + deviations)) + line_n, 0, 3)
+            bar.marker('D', COLORS[len(bars_data) + line_n],
+                       (len(bars_data + bars_dev_top + bars_dev_bottom))
+                       + line_n, 0, 3)
             max_val_l = max(data)
             if axe:
                 bar.axes.type(axes_type + axe)
diff --git a/report.html b/report.html
new file mode 100644
index 0000000..b82cbbd
--- /dev/null
+++ b/report.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Report</title>
+</head>
+
+<body>
+%(body)s
+</body>
+
+</html>
\ No newline at end of file
diff --git a/report.py b/report.py
index 62489f1..32f9d6f 100644
--- a/report.py
+++ b/report.py
@@ -1,15 +1,13 @@
 import sys
 from collections import OrderedDict
 
-import matplotlib.pyplot as plt
 
 import formatters
 from chart import charts
 from utils import ssize_to_b
 from statistic import med_dev, approximate_curve
 
-from disk_perf_test_tool.tests.io_results_loader import (load_files,
-                                                         filter_data)
+from disk_perf_test_tool.io_results_loader import (load_files, filter_data)
 
 
 OPERATIONS = (('async', ('randwrite asynchronous', 'randread asynchronous',
@@ -147,10 +145,6 @@
     open(dest, 'w').write(html)
 
 
-def build_io_chart(res):
-    pass
-
-
 # def render_html_results(ctx):
 #     charts = []
 #     for res in ctx.results:
@@ -163,7 +157,26 @@
     # render_html(bars + lines, dest)
 
 
-def make_io_report(results):
+def io_chart(title, concurence, latv, iops_or_bw, iops_or_bw_dev,
+             legend):
+    bar_data, bar_dev = iops_or_bw, iops_or_bw_dev
+    legend = [legend]
+
+    bar_dev_bottom = []
+    bar_dev_top = []
+    for i in range(len(bar_data)):
+        bar_dev_top.append(bar_data[i] + bar_dev[i])
+        bar_dev_bottom.append(bar_data[i] - bar_dev[i])
+
+    latv = [lat / 1000 for lat in latv]
+    ch = charts.render_vertical_bar(title, legend, [bar_data], [bar_dev_top],
+                                    [bar_dev_bottom],
+                                    scale_x=concurence,
+                                    lines=[(latv, "msec", "rr", "lat")])
+    return str(ch)
+
+
+def make_io_report(results, path):
     for suite_type, test_suite_data in results:
         if suite_type != 'io':
             continue
@@ -186,28 +199,33 @@
 
             concurence, latv, iops_or_bw_v = zip(*data_iter)
             iops_or_bw_v, iops_or_bw_dev_v = zip(*map(med_dev, iops_or_bw_v))
+            latv, _ = zip(*map(med_dev, latv))
 
-            _, ax1 = plt.subplots()
-
-            ax1.plot(concurence, iops_or_bw_v)
-            ax1.errorbar(concurence, iops_or_bw_v, iops_or_bw_dev_v,
-                         linestyle='None',
-                         label="iops_or_bw_v",
-                         marker="*")
-
-            # ynew = approximate_line(ax, ay, ax, True)
-
-            ax2 = ax1.twinx()
-
-            ax2.errorbar(concurence,
-                         [med_dev(lat)[0] / 1000 for lat in latv],
-                         [med_dev(lat)[1] / 1000 for lat in latv],
-                         linestyle='None',
-                         label="iops_or_bw_v",
-                         marker="*")
-            ax2.plot(concurence, [med_dev(lat)[0] / 1000 for lat in latv])
-            plt.show()
-            exit(0)
+            url = io_chart(name_filter, concurence, latv, iops_or_bw_v,
+                           iops_or_bw_dev_v,
+                           fields[2])
+            charts_url.append(url)
+            # _, ax1 = plt.subplots()
+            #
+            # ax1.plot(concurence, iops_or_bw_v)
+            # ax1.errorbar(concurence, iops_or_bw_v, iops_or_bw_dev_v,
+            #              linestyle='None',
+            #              label="iops_or_bw_v",
+            #              marker="*")
+            #
+            # # ynew = approximate_line(ax, ay, ax, True)
+            #
+            # ax2 = ax1.twinx()
+            #
+            # ax2.errorbar(concurence,
+            #              [med_dev(lat)[0] / 1000 for lat in latv],
+            #              [med_dev(lat)[1] / 1000 for lat in latv],
+            #              linestyle='None',
+            #              label="iops_or_bw_v",
+            #              marker="*")
+            # ax2.plot(concurence, [med_dev(lat)[0] / 1000 for lat in latv])
+            # plt.show()
+            # exit(0)
 
             # bw_only = []
 
@@ -224,11 +242,11 @@
 
             # charts_url.append(str(chart_url))
 
-        render_html(charts_url, "results.html")
+        render_html(charts_url, path)
 
 
 def main(args):
-    make_io_report('/tmp/report', load_files(args[1:]))
+    make_io_report(load_files(args[1:]))
     return 0
 
 
diff --git a/run_test.py b/run_test.py
index 6bfad3f..4e3f6ef 100755
--- a/run_test.py
+++ b/run_test.py
@@ -407,13 +407,11 @@
 
 
 def report_stage(cfg, ctx):
-    # html_report = report.make_io_report(ctx.results)
-    # html_rep_fname = cfg['html_report_file']
 
-    # with open(html_rep_fname, "w") as fd:
-    #     fd.write(html_report)
+    html_rep_fname = cfg['html_report_file']
+    report.make_io_report(ctx.results, html_rep_fname)
 
-    # logger.info("Html report were stored in " + html_rep_fname)
+    logger.info("Html report were stored in " + html_rep_fname)
 
     text_rep_fname = cfg_dict['text_report_file']
     with open(text_rep_fname, "w") as fd: