From 639c46e8f85ff867b4206ab0fad1e93c5f8bc5d9 Mon Sep 17 00:00:00 2001
From: "Wang,Jeff"
Date: Wed, 21 Mar 2018 13:30:33 -0700
Subject: [PATCH 1/4] Add manual Save feature.
---
visualdl/logic/pybind.cc | 23 ++++++++++++++++-------
visualdl/logic/sdk.h | 2 +-
visualdl/python/storage.py | 3 +++
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/visualdl/logic/pybind.cc b/visualdl/logic/pybind.cc
index d24ace6c6..ccea54def 100644
--- a/visualdl/logic/pybind.cc
+++ b/visualdl/logic/pybind.cc
@@ -86,6 +86,7 @@ PYBIND11_MODULE(core, m) {
}))
.def("set_mode", &vs::LogWriter::SetMode)
.def("as_mode", &vs::LogWriter::AsMode)
+ .def("save", &vs::LogWriter::Save)
// clang-format off
#define WRITER_ADD_SCALAR(T) \
.def("new_scalar_" #T, [](vs::LogWriter& self, const std::string& tag) { \
@@ -127,10 +128,15 @@ PYBIND11_MODULE(core, m) {
ADD_SCALAR_READER(int64_t);
#undef ADD_SCALAR_READER
-#define ADD_SCALAR_WRITER(T) \
- py::class_>(m, "ScalarWriter__" #T, R"pbdoc(PyBind class. Must instantiate through the LogWriter.)pbdoc") \
- .def("set_caption", &cp::Scalar::SetCaption) \
- .def("add_record", &cp::Scalar::AddRecord, R"pbdoc(add a record with the step and value)pbdoc");
+#define ADD_SCALAR_WRITER(T) \
+ py::class_>( \
+ m, \
+ "ScalarWriter__" #T, \
+ R"pbdoc(PyBind class. Must instantiate through the LogWriter.)pbdoc") \
+ .def("set_caption", &cp::Scalar::SetCaption) \
+ .def("add_record", \
+ &cp::Scalar::AddRecord, \
+ R"pbdoc(add a record with the step and value)pbdoc");
ADD_SCALAR_WRITER(int);
ADD_SCALAR_WRITER(float);
ADD_SCALAR_WRITER(double);
@@ -192,9 +198,12 @@ PYBIND11_MODULE(core, m) {
.def("record", &cp::ImageReader::record)
.def("timestamp", &cp::ImageReader::timestamp);
-#define ADD_HISTOGRAM_WRITER(T) \
- py::class_>(m, "HistogramWriter__" #T, R"pbdoc(PyBind class. Must instantiate through the LogWriter.)pbdoc") \
- .def("add_record", &cp::Histogram::AddRecord, R"pbdoc(add a record with the step and histogram_value)pbdoc");
+#define ADD_HISTOGRAM_WRITER(T) \
+ py::class_>(m, "HistogramWriter__" #T, \
+ R"pbdoc(PyBind class. Must instantiate through the LogWriter.)pbdoc") \
+ .def("add_record", \
+ &cp::Histogram::AddRecord, \
+ R"pbdoc(add a record with the step and histogram_value)pbdoc");
ADD_FULL_TYPE_IMPL(ADD_HISTOGRAM_WRITER)
#undef ADD_HISTOGRAM_WRITER
diff --git a/visualdl/logic/sdk.h b/visualdl/logic/sdk.h
index 810dc5c9f..83ed47850 100644
--- a/visualdl/logic/sdk.h
+++ b/visualdl/logic/sdk.h
@@ -44,7 +44,7 @@ class LogWriter {
mode_ = mode;
storage_.AddMode(mode);
}
-
+ void Save() { storage_.PersistToDisk(); }
LogWriter AsMode(const std::string& mode);
Tablet AddTablet(const std::string& tag);
diff --git a/visualdl/python/storage.py b/visualdl/python/storage.py
index bf17fc1d8..11d5de765 100644
--- a/visualdl/python/storage.py
+++ b/visualdl/python/storage.py
@@ -222,6 +222,9 @@ def histogram(self, tag, num_buckets, type='float'):
}
return types[type](tag, num_buckets)
+ def save(self):
+ self.writer.save()
+
def __enter__(self):
return self
From 24e78de89b948282aa619db6d130dd1b5b07f9be Mon Sep 17 00:00:00 2001
From: "Wang,Jeff"
Date: Wed, 21 Mar 2018 15:48:42 -0700
Subject: [PATCH 2/4] Fix the incorrect style
---
README.md | 4 ++--
demo/keras/TUTORIAL_EN.md | 2 +-
demo/mxnet/TUTORIAL_EN.md | 4 ++--
demo/pytorch/TUTORIAL_EN.md | 2 +-
docs/quick_start_en.md | 4 ++--
visualdl/storage/storage.cc | 32 ++++++++++++--------------------
visualdl/storage/tablet.cc | 18 +++++++++---------
visualdl/storage/tablet.h | 5 +++--
8 files changed, 32 insertions(+), 39 deletions(-)
diff --git a/README.md b/README.md
index 031196fae..f1a359a58 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ VisualDL provides both Python SDK and C++ SDK in order to fit more use cases.
### Python SDK
-VisualDL now supports both Python 2 and Python 3.
+VisualDL now supports both Python 2 and Python 3.
Below is an example of creating a simple Scalar component and inserting data from different timestamps:
```python
@@ -162,7 +162,7 @@ pip install --upgrade dist/visualdl-*.whl
### Run a demo from scratch
```
# vdl_create_scratch_log is a helper commend that creates mock data.
-vdl_create_scratch_log
+vdl_create_scratch_log
visualDL --logdir=scratch_log --port=8080
```
that will start a server locally on port 8080, then
diff --git a/demo/keras/TUTORIAL_EN.md b/demo/keras/TUTORIAL_EN.md
index 74a1cd31d..70098653e 100644
--- a/demo/keras/TUTORIAL_EN.md
+++ b/demo/keras/TUTORIAL_EN.md
@@ -87,4 +87,4 @@ The histograms of the training parameters is as follows:
-The full demonstration code can be downloaded in [here](https://github.com/PaddlePaddle/VisualDL/blob/develop/demo/keras/keras_mnist_demo.py).
\ No newline at end of file
+The full demonstration code can be downloaded in [here](https://github.com/PaddlePaddle/VisualDL/blob/develop/demo/keras/keras_mnist_demo.py).
diff --git a/demo/mxnet/TUTORIAL_EN.md b/demo/mxnet/TUTORIAL_EN.md
index a00257985..34aae9315 100644
--- a/demo/mxnet/TUTORIAL_EN.md
+++ b/demo/mxnet/TUTORIAL_EN.md
@@ -4,7 +4,7 @@ Here we will show you how to use VisualDL in MXNet so that you can visualize the
We will use the MXNet Convolution Neural Network to train the [MNIST](http://yann.lecun.com/exdb/mnist/) dataset as an example.
## Install MXNet
-Please install MXNet according to MXNet's [official website](https://mxnet.incubator.apache.org/install/index.html)
+Please install MXNet according to MXNet's [official website](https://mxnet.incubator.apache.org/install/index.html)
and verify that the installation is successful.
>>> import mxnet as mx
@@ -58,7 +58,7 @@ lenet_model.fit(train_iter,
```
That's all. In the training process of MXNet, our callback function is called to record the accuracy at the end of each training batch.
-The rate of accuracy will continue to rise until more than 95%.
+The rate of accuracy will continue to rise until more than 95%.
The following is the accuracy of the two epochs:
diff --git a/demo/pytorch/TUTORIAL_EN.md b/demo/pytorch/TUTORIAL_EN.md
index 7801b604f..f5d1e2778 100644
--- a/demo/pytorch/TUTORIAL_EN.md
+++ b/demo/pytorch/TUTORIAL_EN.md
@@ -167,7 +167,7 @@ for epoch in range(5): # loop over the dataset multiple times
print('Finished Training')
```
-PyTorch support ONNX standard and it can export its model into ONNX.
+PyTorch support ONNX standard and it can export its model into ONNX.
PyTorch runs a single round of inference to trace the graph. We use a dummy input to run the model to produce the ONNX model
```python
diff --git a/docs/quick_start_en.md b/docs/quick_start_en.md
index 2fa179cda..1fc6a0da5 100644
--- a/docs/quick_start_en.md
+++ b/docs/quick_start_en.md
@@ -27,10 +27,10 @@ logw = LogWriter("./random_log", sync_cycle=10000)
```
The first parameter points to a folder; the second parameter `sync_cycle` specifies out of how memory operations should be
-store the data into hard drive.
+store the data into hard drive.
### sync_cycle
-Writing is a heavy operation. Setting `sync_cycle` might slow down your training.
+Writing is a heavy operation. Setting `sync_cycle` might slow down your training.
A good starting point is to set the `sync_cycle` to be at least twice the amount of data point your would like to capture.
There are different modes for model training, such as training, validating and testing. All these correspond to `mode' in VisualDL.
diff --git a/visualdl/storage/storage.cc b/visualdl/storage/storage.cc
index 29a8704a7..8dc4acdc8 100644
--- a/visualdl/storage/storage.cc
+++ b/visualdl/storage/storage.cc
@@ -32,9 +32,7 @@ Storage::Storage(const Storage& other)
dir_ = other.dir_;
}
-Storage::~Storage() {
- PersistToDisk();
-}
+Storage::~Storage() { PersistToDisk(); }
void Storage::AddMode(const std::string& x) {
// avoid duplicate modes.
@@ -54,13 +52,9 @@ Tablet Storage::AddTablet(const std::string& x) {
return Tablet(&(*tablets_)[x], this);
}
-void Storage::SetDir(const std::string& dir) {
- *dir_ = dir;
-}
+void Storage::SetDir(const std::string& dir) { *dir_ = dir; }
-std::string Storage::dir() const {
- return *dir_;
-}
+std::string Storage::dir() const { return *dir_; }
void Storage::PersistToDisk() { PersistToDisk(*dir_); }
@@ -70,27 +64,25 @@ void Storage::PersistToDisk(const std::string& dir) {
fs::SerializeToFile(*data_, meta_path(dir));
for (auto tag : data_->tags()) {
- if (modified_tablet_set_.count(tag) > 0){
- auto it = tablets_->find(tag);
- CHECK(it != tablets_->end()) << "tag " << tag << " not exist.";
- fs::SerializeToFile(it->second, tablet_path(dir, tag));
+ if (modified_tablet_set_.count(tag) > 0) {
+ auto it = tablets_->find(tag);
+ CHECK(it != tablets_->end()) << "tag " << tag << " not exist.";
+ fs::SerializeToFile(it->second, tablet_path(dir, tag));
}
}
modified_tablet_set_.clear();
}
-Storage* Storage::parent() {
- return this;
-}
+Storage* Storage::parent() { return this; }
void Storage::MarkTabletModified(const std::string tag) {
- modified_tablet_set_.insert(tag);
+ modified_tablet_set_.insert(tag);
}
void Storage::AddTag(const std::string& x) {
- *data_->add_tags() = x;
- WRITE_GUARD
- }
+ *data_->add_tags() = x;
+ WRITE_GUARD
+}
// StorageReader
std::vector StorageReader::all_tags() {
diff --git a/visualdl/storage/tablet.cc b/visualdl/storage/tablet.cc
index fc8db3783..b36f6f082 100644
--- a/visualdl/storage/tablet.cc
+++ b/visualdl/storage/tablet.cc
@@ -18,18 +18,18 @@ limitations under the License. */
namespace visualdl {
void Tablet::SetTag(const std::string& mode, const std::string& tag) {
- auto internal_tag = mode + "/" + tag;
- string::TagEncode(internal_tag);
- internal_encoded_tag_ = internal_tag;
- data_->set_tag(internal_tag);
- WRITE_GUARD
+ auto internal_tag = mode + "/" + tag;
+ string::TagEncode(internal_tag);
+ internal_encoded_tag_ = internal_tag;
+ data_->set_tag(internal_tag);
+ WRITE_GUARD
}
Record Tablet::AddRecord() {
- parent()->MarkTabletModified(internal_encoded_tag_);
- IncTotalRecords();
- WRITE_GUARD
- return Record(data_->add_records(), parent());
+ parent()->MarkTabletModified(internal_encoded_tag_);
+ IncTotalRecords();
+ WRITE_GUARD
+ return Record(data_->add_records(), parent());
}
TabletReader Tablet::reader() { return TabletReader(*data_); }
diff --git a/visualdl/storage/tablet.h b/visualdl/storage/tablet.h
index b0907445b..f0c2cc86c 100644
--- a/visualdl/storage/tablet.h
+++ b/visualdl/storage/tablet.h
@@ -29,11 +29,12 @@ struct TabletReader;
* Tablet is a helper for operations on storage::Tablet.
*/
struct Tablet {
- enum Type { kScalar = 0, kHistogram = 1, kImage = 2, kUnknown = -1};
+ enum Type { kScalar = 0, kHistogram = 1, kImage = 2, kUnknown = -1 };
DECL_GUARD(Tablet);
- Tablet(storage::Tablet* x, Storage* parent) : data_(x), x_(parent), internal_encoded_tag_("") {}
+ Tablet(storage::Tablet* x, Storage* parent)
+ : data_(x), x_(parent), internal_encoded_tag_("") {}
static Type type(const std::string& name) {
if (name == "scalar") {
From bd8534485b6edcc53278d8a45a10d214f5f159c2 Mon Sep 17 00:00:00 2001
From: "Wang,Jeff"
Date: Wed, 21 Mar 2018 17:30:15 -0700
Subject: [PATCH 3/4] Add feature to record Text
---
visualdl/logic/pybind.cc | 27 ++++++++++++++++++++++++---
visualdl/logic/sdk.cc | 31 +++++++++++++++++++++++++++++++
visualdl/logic/sdk.h | 34 ++++++++++++++++++++++++++++++++++
visualdl/python/storage.py | 8 ++++++++
4 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/visualdl/logic/pybind.cc b/visualdl/logic/pybind.cc
index ccea54def..f5e292f57 100644
--- a/visualdl/logic/pybind.cc
+++ b/visualdl/logic/pybind.cc
@@ -74,9 +74,14 @@ PYBIND11_MODULE(core, m) {
#undef READER_ADD_HISTOGRAM
// clang-format on
- .def("get_image", [](vs::LogReader& self, const std::string& tag) {
+ .def("get_image",
+ [](vs::LogReader& self, const std::string& tag) {
+ auto tablet = self.tablet(tag);
+ return vs::components::ImageReader(self.mode(), tablet);
+ })
+ .def("get_text", [](vs::LogReader& self, const std::string& tag) {
auto tablet = self.tablet(tag);
- return vs::components::ImageReader(self.mode(), tablet);
+ return vs::components::TextReader(tablet);
});
// clang-format on
@@ -113,7 +118,11 @@ PYBIND11_MODULE(core, m) {
int step_cycle) {
auto tablet = self.AddTablet(tag);
return vs::components::Image(tablet, num_samples, step_cycle);
- });
+ })
+ .def("new_text", [](vs::LogWriter& self, const std::string& tag) {
+ auto tablet = self.AddTablet(tag);
+ return vs::components::Text(tablet);
+ });
//------------------- components --------------------
#define ADD_SCALAR_READER(T) \
@@ -198,6 +207,18 @@ PYBIND11_MODULE(core, m) {
.def("record", &cp::ImageReader::record)
.def("timestamp", &cp::ImageReader::timestamp);
+ py::class_(m, "TextWriter")
+ .def("set_caption", &cp::Text::SetCaption)
+ .def("add_record", &cp::Text::AddRecord);
+
+ py::class_(m, "TextReader")
+ .def("records", &cp::TextReader::records)
+ .def("ids", &cp::TextReader::ids)
+ .def("timestamps", &cp::TextReader::timestamps)
+ .def("caption", &cp::TextReader::caption)
+ .def("total_records", &cp::TextReader::total_records)
+ .def("size", &cp::TextReader::size);
+
#define ADD_HISTOGRAM_WRITER(T) \
py::class_>(m, "HistogramWriter__" #T, \
R"pbdoc(PyBind class. Must instantiate through the LogWriter.)pbdoc") \
diff --git a/visualdl/logic/sdk.cc b/visualdl/logic/sdk.cc
index 3edc8c276..db58e73ea 100644
--- a/visualdl/logic/sdk.cc
+++ b/visualdl/logic/sdk.cc
@@ -321,6 +321,37 @@ DECL_BASIC_TYPES_CLASS_IMPL(class, ScalarReader)
DECL_BASIC_TYPES_CLASS_IMPL(struct, Histogram)
DECL_BASIC_TYPES_CLASS_IMPL(struct, HistogramReader)
+std::vector TextReader::records() const {
+ std::vector res;
+ for (int i = 0; i < total_records(); i++) {
+ res.push_back(reader_.record(i).data(0).template Get());
+ }
+ return res;
+}
+
+std::vector TextReader::ids() const {
+ std::vector res;
+ for (int i = 0; i < reader_.total_records(); i++) {
+ res.push_back(reader_.record(i).id());
+ }
+ return res;
+}
+
+std::vector TextReader::timestamps() const {
+ std::vector res;
+ for (int i = 0; i < reader_.total_records(); i++) {
+ res.push_back(reader_.record(i).timestamp());
+ }
+ return res;
+}
+
+std::string TextReader::caption() const {
+ CHECK(!reader_.captions().empty()) << "no caption";
+ return reader_.captions().front();
+}
+
+size_t TextReader::size() const { return reader_.total_records(); }
+
} // namespace components
} // namespace visualdl
diff --git a/visualdl/logic/sdk.h b/visualdl/logic/sdk.h
index 83ed47850..313563c04 100644
--- a/visualdl/logic/sdk.h
+++ b/visualdl/logic/sdk.h
@@ -284,6 +284,40 @@ struct HistogramReader {
TabletReader reader_;
};
+struct Text {
+ Text(Tablet tablet) : tablet_(tablet) {}
+ void SetCaption(const std::string cap) {
+ tablet_.SetCaptions(std::vector({cap}));
+ }
+
+ void AddRecord(int id, std::string value) {
+ auto record = tablet_.AddRecord();
+ record.SetId(id);
+ auto entry = record.AddData();
+
+ time_t time = std::time(nullptr);
+ record.SetTimeStamp(time);
+ entry.Set(value);
+ }
+
+private:
+ Tablet tablet_;
+};
+
+struct TextReader {
+ TextReader(TabletReader reader) : reader_(reader) {}
+
+ std::vector records() const;
+ std::vector ids() const;
+ std::vector timestamps() const;
+ std::string caption() const;
+ size_t total_records() const { return reader_.total_records(); }
+ size_t size() const;
+
+private:
+ TabletReader reader_;
+};
+
} // namespace components
} // namespace visualdl
diff --git a/visualdl/python/storage.py b/visualdl/python/storage.py
index 11d5de765..4b519dd66 100644
--- a/visualdl/python/storage.py
+++ b/visualdl/python/storage.py
@@ -115,6 +115,10 @@ def histogram(self, tag, type='float'):
check_tag_name_valid(tag)
return type2scalar[type](tag)
+ def text(self, tag):
+ check_tag_name_valid(tag)
+ return self.reader.get_text(tag)
+
def __enter__(self):
return self
@@ -222,6 +226,10 @@ def histogram(self, tag, num_buckets, type='float'):
}
return types[type](tag, num_buckets)
+ def text(self, tag):
+ check_tag_name_valid(tag)
+ return self.writer.new_text(tag)
+
def save(self):
self.writer.save()
From 5b61d0ea39ae038a2be5755a26653059215f4dfe Mon Sep 17 00:00:00 2001
From: "Wang,Jeff"
Date: Thu, 22 Mar 2018 16:11:50 -0700
Subject: [PATCH 4/4] Create a simple UI for text preview.
---
frontend/mock/data/plugin/texts/tags.js | 39 +++++
frontend/mock/data/plugin/texts/texts.js | 38 +++++
frontend/src/common/component/AppMenu.vue | 5 +
frontend/src/router/index.js | 6 +
frontend/src/service.js | 4 +
frontend/src/texts/Texts.vue | 167 ++++++++++++++++++++++
frontend/src/texts/index.js | 9 ++
frontend/src/texts/ui/Chart.vue | 146 +++++++++++++++++++
frontend/src/texts/ui/ChartPage.vue | 78 ++++++++++
frontend/src/texts/ui/Config.vue | 73 ++++++++++
10 files changed, 565 insertions(+)
create mode 100644 frontend/mock/data/plugin/texts/tags.js
create mode 100644 frontend/mock/data/plugin/texts/texts.js
create mode 100644 frontend/src/texts/Texts.vue
create mode 100644 frontend/src/texts/index.js
create mode 100644 frontend/src/texts/ui/Chart.vue
create mode 100644 frontend/src/texts/ui/ChartPage.vue
create mode 100644 frontend/src/texts/ui/Config.vue
diff --git a/frontend/mock/data/plugin/texts/tags.js b/frontend/mock/data/plugin/texts/tags.js
new file mode 100644
index 000000000..a89f897cc
--- /dev/null
+++ b/frontend/mock/data/plugin/texts/tags.js
@@ -0,0 +1,39 @@
+/**
+ * get mock data
+ *
+ * @param {string} path request path
+ * @param {Object} queryParam query params
+ * @param {Object} postParam post params
+ * @return {Object}
+ */
+module.exports = function (path, queryParam, postParam) {
+ return {
+ // moock delay
+ _timeout: 0,
+ // mock http status
+ _status: 200,
+ // mock response data
+ _data: {
+ status: 0,
+ msg: 'SUCCESS',
+ data: {
+ "test": {
+ "layer3/generated/animal": {
+ "displayName": "layer3/generated/animal",
+ "description": ""
+ }
+ },
+ "train": {
+ "layer3/generated/animal": {
+ "displayName": "layer3/generated/animal",
+ "description": ""
+ },
+ "layer3/generated/flower": {
+ "displayName": "layer3/generated/flower",
+ "description": ""
+ },
+ }
+ }
+ }
+ };
+};
diff --git a/frontend/mock/data/plugin/texts/texts.js b/frontend/mock/data/plugin/texts/texts.js
new file mode 100644
index 000000000..80c62985c
--- /dev/null
+++ b/frontend/mock/data/plugin/texts/texts.js
@@ -0,0 +1,38 @@
+/**
+ * get mock data
+ *
+ * @param {string} path request path
+ * @param {Object} queryParam query params
+ * @param {Object} postParam post params
+ * @return {Object}
+ */
+module.exports = function (path, queryParam, postParam) {
+ if (queryParam.run === 'train') {
+ return {
+ // moock delay
+ _timeout: 0,
+ // mock http status
+ _status: 200,
+ // mock response data
+ _data: {
+ status: 0,
+ msg: 'SUCCESS',
+ data: [[1511842145.705075, 1, "Hello 1"], [1511842145.7388, 2, "Hello 2"], [1511842145.774563, 3, "Hello 3"], [1511842145.806828, 4, "Hello 4"], [1511842145.838082, 5, "Hello 5"], [1511842145.868955, 6, "Hello 6"], [1511842145.899323, 7, "Hello 7"], [1511842145.930518, 8, "Hello 8"], [1511842145.96089, 9, "Hello 7"], [1511842146.460557, 11, "Hello 11"], [1511842146.4952, 12, "Hello 12"], [1511842146.525936, 13, "Hello 13"], [1511842146.556059, 14, "Hello 14"], [1511842146.648703, 15, "Hello 15"], [1511842146.683295, 16, "Hello 16"], [1511842146.719782, 17, "Hello 17"], [1511842146.752392, 18, "Hello 18"]]
+ }
+ }
+ }
+ else {
+ return {
+ // moock delay
+ _timeout: 0,
+ // mock http status
+ _status: 200,
+ // mock response data
+ _data: {
+ status: 0,
+ msg: 'SUCCESS',
+ data: [[1511842145.514333, 0, "Hello 0"], [1511842146.427384, 10, "Hello 10"], [1511842147.260405, 20, "Hello 20"], [1511842148.019018, 30, "Hello 30 "], [1511842148.793569, 40, "Hello 40 "], [1511842149.610228, 50, "Hello 50 "], [1511842150.437095, 60, "Hello 60"], [1511842151.254679, 70, "Hello 70"], [1511842152.039353, 80, "Hello 80"], [1511842152.800043, 90, "Hello 90"]]
+ }
+ }
+ }
+};
diff --git a/frontend/src/common/component/AppMenu.vue b/frontend/src/common/component/AppMenu.vue
index 0999df9bd..8041865ca 100644
--- a/frontend/src/common/component/AppMenu.vue
+++ b/frontend/src/common/component/AppMenu.vue
@@ -41,6 +41,11 @@ export default {
url: '/graphs',
title: 'GRAPHS',
name: 'graphs'
+ },
+ {
+ url: '/texts',
+ title: 'TEXTS',
+ name: 'texts'
}
]
}
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index 6832582f2..353f25cd4 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -5,6 +5,7 @@ import Scalars from '@/scalars/Scalars'
import Histogram from '@/histogram/Histogram'
import Images from '@/images/Images'
import Graph from '@/graph/Graph'
+import Texts from '@/texts/Texts'
Vue.use(Router)
@@ -30,5 +31,10 @@ export default new Router({
name: 'Graph',
component: Graph
},
+ {
+ path: '/texts',
+ name: 'Texts',
+ component: Texts
+ }
]
})
diff --git a/frontend/src/service.js b/frontend/src/service.js
index 743936df6..012074d8e 100644
--- a/frontend/src/service.js
+++ b/frontend/src/service.js
@@ -15,3 +15,7 @@ export const getPluginHistogramsTags = makeService('/data/plugin/histograms/tags
export const getPluginHistogramsHistograms = makeService('/data/plugin/histograms/histograms');
export const getPluginGraphsGraph = makeService('/data/plugin/graphs/graph');
+
+export const getPluginTextsTags = makeService('/data/plugin/texts/tags');
+
+export const getPluginTextsTexts = makeService('/data/plugin/texts/texts');
diff --git a/frontend/src/texts/Texts.vue b/frontend/src/texts/Texts.vue
new file mode 100644
index 000000000..9afefc5de
--- /dev/null
+++ b/frontend/src/texts/Texts.vue
@@ -0,0 +1,167 @@
+
+