Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/backend/BackendSVG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ void BackendSVG::clear_tooltip() {
m_onmouseout_tooltip.clear();
}

void BackendSVG::stroke_style(const std::string &style) {
m_line_style = "stroke-dasharray=\"" + style + "\"";
}

void BackendSVG::stroke_width(const float lw) {
m_linewidth =
std::string("stroke-width=\"") + std::to_string(lw) + std::string("\"");
Expand All @@ -269,7 +273,7 @@ void BackendSVG::fill_color(const RGBA &color) {

void BackendSVG::stroke() {
m_out << "<path d=\"" << m_path << "\" " << m_line_color << ' ' << m_linewidth
<< " fill-opacity=\"0\"";
<< " fill-opacity=\"0\" " << m_line_style;
if (!m_transform.is_identity()) {
m_out << ' ' << m_transform.to_string();
}
Expand Down
4 changes: 4 additions & 0 deletions src/backend/BackendSVG.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class BackendSVG : public AnimatedBackend {

std::string m_linewidth;
std::string m_line_color;
std::string m_line_style;
std::string m_fill_color;
std::string m_path;
std::string m_font_face;
Expand Down Expand Up @@ -342,6 +343,9 @@ class BackendSVG : public AnimatedBackend {
/// @see tooltip()
void clear_tooltip();

/// sets the current line style
void stroke_style(const std::string &style);

/// sets the current stroke width
void stroke_width(const float lw);

Expand Down
20 changes: 20 additions & 0 deletions src/frontend/Axis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ class Axis : public Drawable {
/// the number of ticks displayed on the y axis
int m_ny_ticks;

/// the length of maximum yticks char length
int m_max_ytick_char_len = 0;
std::string m_max_ytick_char = "";

/// the length (in pixels) of each tick
float m_tick_len;

Expand Down Expand Up @@ -219,6 +223,22 @@ class Axis : public Drawable {
/// gets the number of ticks on this axis
Vector<int, 2> get_ticks() const { return {m_nx_ticks, m_ny_ticks}; }

/// get the number of maximum yticks length (in pixels)
int max_ytick_pixels() const {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This calculation should really be done by the Style class, but since the calculation is still not correct please put it inline in Axis::draw_common_ylabel along with a TODO comment

/// Convertion from length * font_size to pixels
/// The scale factor, i.e., 1.25, is for Roboto font (https://bugbox.clickteam.com/threads/82514-Useful-Roboto-Font-Size-Pixel-Heights!)
return int(this->max_ytick_char_len() * m_style.font_size() / 1.25);
}

// get the number of maximum char length of yticks
int max_ytick_char_len() const { return m_max_ytick_char_len; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_max_ytick_char_len depends on if the drawing code is run yet or not. please remove this method and keep this value purely private to the class


// get default font size
float font_size() const { return m_style.font_size(); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this too as is not needed.


// get maximum char
std::string max_ytick_char() const { return m_max_ytick_char; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and remove this


private:
/// Create a new Geometry on this axis and return a shared pointer to it.
///
Expand Down
15 changes: 13 additions & 2 deletions src/frontend/Axis.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "frontend/Axis.hpp"
#include "frontend/Geometry.hpp"
#include "frontend/Line.hpp"
#include <iostream>
#include <cstring>

namespace trase {

Expand Down Expand Up @@ -96,18 +98,28 @@ template <typename Backend> void Axis::draw_common_ticks(Backend &backend) {

backend.text_align(ALIGN_RIGHT | ALIGN_MIDDLE);

size_t max_char_len = this->max_ytick_char_len();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
size_t max_char_len = this->max_ytick_char_len();
size_t max_char_len = 0;

// y ticks
for (std::size_t i = 0; i < m_tick_info.y_pos.size(); ++i) {

const float pos = m_tick_info.y_pos[i];
const float val = m_tick_info.y_val[i];

backend.move_to(vfloat2_t(m_pixels.bmin[0] - m_tick_len / 2, pos));
backend.line_to(vfloat2_t(m_pixels.bmin[0], pos));
std::snprintf(buffer, sizeof(buffer), "%.*g", m_sig_digits + 1, val);

if (strlen(buffer) > max_char_len) {
max_char_len = strlen(buffer);
m_max_ytick_char = std::string(buffer);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think m_max_ytick_char is not used? If so then remove

}

backend.text(vfloat2_t(m_pixels.bmin[0] - m_tick_len / 2, pos), buffer,
NULL);
}

m_max_ytick_char_len = max_char_len;

backend.stroke_color(RGBA(0, 0, 0, 255));
backend.stroke_width(m_style.line_width() / 2);
backend.stroke();
Expand Down Expand Up @@ -167,8 +179,7 @@ template <typename Backend> void Axis::draw_common_ylabel(Backend &backend) {
}

backend.text_align(ALIGN_CENTER | ALIGN_BOTTOM);
const vfloat2_t point = vfloat2_t(
m_pixels.bmin[0] - 0.05f * (m_pixels.bmax[0] - m_pixels.bmin[0]),
const vfloat2_t point = vfloat2_t(m_pixels.bmin[0] - this->max_ytick_pixels(),
0.5f * (m_pixels.bmax[1] + m_pixels.bmin[1]));
backend.translate(point);
backend.rotate(-pi / 2.0f);
Expand Down
1 change: 1 addition & 0 deletions src/frontend/Line.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ template <typename Backend> void Line::draw_plot(Backend &backend) {

backend.stroke_color(m_style.color());
backend.stroke_width(m_style.line_width());
backend.stroke_style(m_style.line_style());
backend.stroke();
}

Expand Down
16 changes: 16 additions & 0 deletions src/util/Style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ namespace trase {

float Style::line_width() const noexcept { return m_line_width; }

std::string Style::line_style() const noexcept {
if (m_line_style == "solid")
return "0";
else if (m_line_style == "dashed")
return "10,5";
else if (m_line_style == "dotted")
return "10,3,2";
else
return "0";
}

float Style::font_size() const noexcept { return m_font_size; }

RGBA Style::color() const noexcept { return m_color; }
Expand All @@ -48,6 +59,11 @@ Style &Style::line_width(const float lineWidth) noexcept {
return *this;
}

Style &Style::line_style(const std::string lineStyle) noexcept {
m_line_style = lineStyle;
return *this;
}

Style &Style::font_size(const float fontSize) noexcept {
m_font_size = fontSize;
return *this;
Expand Down
10 changes: 10 additions & 0 deletions src/util/Style.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define STYLE_H_

#include "util/Colors.hpp"
#include <string>

namespace trase {

Expand All @@ -45,6 +46,9 @@ class Style {
/// the line width
float m_line_width{3.f};

/// the line style
std::string m_line_style{"solid"};

/// the font size
float m_font_size{18.f};

Expand All @@ -61,6 +65,9 @@ class Style {
/// get the current line width
float line_width() const noexcept;

/// get the current line width
std::string line_style() const noexcept;

/// get the current font size
float font_size() const noexcept;

Expand All @@ -73,6 +80,9 @@ class Style {
/// set the new line width
Style &line_width(float lineWidth) noexcept;

/// set the new line style
Style &line_style(std::string lineStyle) noexcept;

/// set the new font size
Style &font_size(float fontSize) noexcept;

Expand Down
6 changes: 3 additions & 3 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ add_executable (
TestTransformMatrix.cpp
TestVector.cpp
TestLegend.cpp
TestLines.cpp
)

if (CURL_FOUND)
target_sources(trase_test PRIVATE TestCSVDownloader.cpp)
endif (CURL_FOUND)

target_include_directories (trase_test PRIVATE tests)
target_link_libraries (trase_test PRIVATE trase)
add_test (the_trase_test trase_test)


add_test (the_trase_test trase_test)
33 changes: 33 additions & 0 deletions tests/TestAxis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,36 @@ TEST_CASE("set number of ticks", "[axis]") {
CHECK(ax->get_ticks()[0] == 10);
CHECK(ax->get_ticks()[1] == 10);
}


TEST_CASE("ylabel position: case 1", "[axis]") {
std::vector<double> predicted_data = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename these vectors x and y and use these below rather than creating another pair of vectors

-13.8881, -13.8671, -13.8361, -13.7881, -13.7681, -13.7381, -12.6881, -12.661, -12.6481
};
std::vector<double> exp_data = {
-13.8881, -13.8671, -13.8361, -13.7881, -13.7681, -13.7381, -12.6881, -12.661, -12.6481
};

auto fig = figure();
auto ax = fig->axis();
int predicted_size = predicted_data.size();
int exp_size = exp_data.size();

std::vector<float> x(predicted_size);
std::vector<float> y(exp_size);
for (int i = 0; i < predicted_size; ++i) {
x[i] = predicted_data[i];
}
for (int i = 0; i < exp_size; ++i) {
y[i] = exp_data[i];
}

auto data = create_data().x(x).y(y);
auto plt = ax->points(data);

ax->xlabel("Pred. Target");
ax->ylabel("Exp. Target");

DummyDraw::draw("axis", fig);
}

101 changes: 101 additions & 0 deletions tests/TestLines.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
Copyright (c) 2018, University of Oxford.
All rights reserved.

University of Oxford means the Chancellor, Masters and Scholars of the
University of Oxford, having an administrative office at Wellington
Square, Oxford OX1 2JD, UK.

This file is part of the Oxford RSE C++ Template project.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "catch.hpp"

#include "DummyDraw.hpp"

#include "trase.hpp"
#include <fstream>
#include <random>

using namespace trase;

TEST_CASE("Lines creation", "[lines]") {
// create figure and axis
auto fig = figure();
auto ax = fig->axis();

// create x and y vectors
const int n = 100;
std::vector<float> x(n);
std::vector<float> y(n);
const float k = 1.f;
auto logistic = [k](const float x) { return 1.f / (1.f + std::exp(-k * x)); };
for (int i = 0; i < n; ++i) {
x[i] = -6.f + 12.f * static_cast<float>(i) / n;
y[i] = logistic(x[i]);
}

// create a trase dataset and then plot it using a line geometry
auto data = create_data().x(x).y(y);
auto plt = ax->line(data);

// set line color = red and line width = 10
plt->style().color(RGBA(255, 0, 0)).line_width(10).line_style("dashed");

// label axis
ax->xlabel("x");
ax->ylabel("y");

DummyDraw::draw("lines", fig);
}

TEST_CASE("Hybrids lines creation", "[lines]") {

auto fig = figure();
auto ax = fig->axis();

{
auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{0, 1});
auto plt = ax->line(data);
plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("solid");
}

{
auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{0.5, 1.5});
auto plt = ax->line(data);
plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("dashed");
}

{
auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{-0.5, 0.5});
auto plt = ax->line(data);
plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("dotted");
}

ax->xlabel("Pred. Target");
ax->ylabel("Exp. Target");

DummyDraw::draw("lines", fig);
}