diff --git a/.gitignore b/.gitignore
index e589a4c..e5a9a31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
 /lab1.depend
 /lab1.layout
 /unittest.layout
+/unittest.depend
diff --git a/main.cpp b/main.cpp
index d78849b..fd793a9 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,8 +1,9 @@
 #include "histogram.h"
+#include "svg.h"
 
 int main() {
     auto in = input_data();
     auto bins = make_histogram(in.numbers, in.bin_count);
-    show_histogram_text(bins);
+    show_histogram_svg(bins);
     return 0;
 }
diff --git a/marks.svg b/marks.svg
new file mode 100644
index 0000000..e69de29
diff --git a/marks.txt b/marks.txt
new file mode 100644
index 0000000..2cdb9aa
--- /dev/null
+++ b/marks.txt
@@ -0,0 +1,3 @@
+10
+3 3 4 4 4 4 4 5 5 5
+3
diff --git a/svg.cpp b/svg.cpp
new file mode 100644
index 0000000..ed9bfed
--- /dev/null
+++ b/svg.cpp
@@ -0,0 +1,51 @@
+#include "svg.h"
+#include <iostream>
+
+void svg_begin(double width, double height) {
+    std::cout << "<?xml version='1.0' encoding='UTF-8'?>\n";
+    std::cout << "<svg width='" << width << "' height='" << height << "' "
+              << "viewBox='0 0 " << width << " " << height << "' "
+              << "xmlns='http://www.w3.org/2000/svg'>\n";
+}
+
+void svg_end() {
+    std::cout << "</svg>\n";
+}
+
+void svg_text(double left, double baseline, const std::string& text) {
+    std::cout << "<text x='" << left << "' y='" << baseline << "'>" << text << "</text>\n";
+}
+
+void svg_rect(double x, double y, double width, double height,
+              const std::string& stroke, const std::string& fill) {
+    std::cout << "<rect x='" << x << "' y='" << y << "' "
+              << "width='" << width << "' height='" << height << "' "
+              << "stroke='" << stroke << "' fill='" << fill << "' />\n";
+}
+
+void show_histogram_svg(const std::vector<size_t>& bins) {
+    const size_t IMAGE_WIDTH = 400;
+    const size_t IMAGE_HEIGHT = 300;
+    const size_t TEXT_LEFT = 20;
+    const size_t TEXT_BASELINE = 20;
+    const size_t TEXT_WIDTH = 50;
+    const size_t BIN_HEIGHT = 30;
+    const size_t BLOCK_WIDTH = 10;
+
+    svg_begin(IMAGE_WIDTH, IMAGE_HEIGHT);
+
+    double top = 0;
+    size_t max_count = 0;
+    for (size_t count : bins) {
+        if (count > max_count) max_count = count;
+    }
+
+    for (size_t bin : bins) {
+        const double bin_width = static_cast<double>(bin) / max_count * (IMAGE_WIDTH - TEXT_WIDTH);
+        svg_text(TEXT_LEFT, top + TEXT_BASELINE, std::to_string(bin));
+        svg_rect(TEXT_WIDTH, top, bin_width, BIN_HEIGHT, "black", "#aaffaa");
+        top += BIN_HEIGHT;
+    }
+
+    svg_end();
+}
diff --git a/svg.h b/svg.h
new file mode 100644
index 0000000..62c8e73
--- /dev/null
+++ b/svg.h
@@ -0,0 +1,10 @@
+#pragma once
+#include <vector>
+#include <string>
+
+void svg_begin(double width, double height);
+void svg_end();
+void svg_text(double left, double baseline, const std::string& text);
+void svg_rect(double x, double y, double width, double height,
+              const std::string& stroke = "black", const std::string& fill = "black");
+void show_histogram_svg(const std::vector<size_t>& bins);
diff --git a/unittest.cpp b/unittest.cpp
index e69de29..a9ba7e5 100644
--- a/unittest.cpp
+++ b/unittest.cpp
@@ -0,0 +1,12 @@
+#define DOCTEST_CONFIG_NO_MULTITHREADING
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+#include "histogram_internal.h"
+
+TEST_CASE("distinct positive numbers") {
+    double min = 0;
+    double max = 0;
+    find_minmax({1, 2}, min, max);
+    CHECK(min == 1);
+    CHECK(max == 2);
+}