36 #include <type_traits>
40 #include <sciplot/Constants.hpp>
41 #include <sciplot/Enums.hpp>
42 #include <sciplot/Palettes.hpp>
51 auto str(
const T& val) -> std::string
59 inline auto str(
const char* word) -> std::string
65 inline auto str() -> std::string
71 inline auto trimleft(std::string str,
unsigned char character =
' ') -> std::string
73 str.erase(str.begin(), std::find_if(str.begin(), str.end(),
75 { return ch != character; }));
80 inline auto trimright(std::string str,
unsigned char character =
' ') -> std::string
82 str.erase(std::find_if(str.rbegin(), str.rend(),
84 { return ch != character; })
91 inline auto trim(std::string str,
unsigned char character =
' ') -> std::string
93 return trimleft(trimright(str, character), character);
97 inline auto collapseWhitespaces(std::string s) -> std::string
99 s.erase(std::unique(std::begin(s), std::end(s),
100 [](
unsigned char a,
unsigned char b)
101 {
return std::isspace(a) && std::isspace(b); }),
107 inline auto removeExtraWhitespaces(std::string s) -> std::string
109 return trim(collapseWhitespaces(s));
113 template <
typename VectorType>
114 auto minsize(
const VectorType& v) -> std::size_t
120 template <
typename VectorType,
typename... Args>
121 auto minsize(
const VectorType& v,
const Args&... args) -> std::size_t
123 return std::min<decltype(v.size())>(v.size(), minsize(args...));
127 template <
typename T>
128 constexpr
auto isString = std::is_same_v<std::decay_t<T>, std::string>;
131 template <
typename V>
132 constexpr
auto isStringVector = isString<decltype(std::declval<V>()[0])>;
135 template <
typename T>
136 auto escapeIfNeeded(
const T& val)
138 if constexpr (isString<T>)
139 return "\"" + val +
"\"";
141 return std::isfinite(
static_cast<double>(val)) ? internal::str(val) : MISSING_INDICATOR;
145 template <
typename VectorType>
146 auto writeline(std::ostream& out, std::size_t i,
const VectorType& v) -> std::ostream&
148 out << escapeIfNeeded(v[i]) <<
'\n';
153 template <
typename VectorType,
typename... Args>
154 auto writeline(std::ostream& out, std::size_t i,
const VectorType& v,
const Args&... args) -> std::ostream&
156 out << escapeIfNeeded(v[i]) <<
" ";
157 writeline(out, i, args...);
162 template <
typename... Args>
163 auto write(std::ostream& out,
const Args&... args) -> std::ostream&
165 const auto size = minsize(args...);
166 for (std::size_t i = 0; i < size; ++i)
167 writeline(out, i, args...);
177 inline auto titlestr(std::string word) -> std::string
179 return word ==
"columnheader" ? word :
"'" + word +
"'";
184 inline auto optionStr(std::string option) -> std::string
186 return option.size() ? (option +
" ") :
"";
191 inline auto optionValueStr(std::string option, std::string value) -> std::string
193 return value.size() ? (option +
" " + value +
" ") :
"";
198 inline auto cmdValueStr(std::string cmd, std::string value) -> std::string
200 return value.size() ? (cmd +
" " + value +
"\n") :
"";
205 inline auto cmdValueEscapedStr(std::string cmd, std::string value) -> std::string
207 return value.size() ? (cmd +
" '" + value +
"'\n") :
"";
211 inline auto figureSizeStr(
double sx,
double sy) -> std::string
213 return internal::str(sx) +
"," + internal::str(sy);
217 inline auto canvasSizeStr(std::size_t width, std::size_t height,
bool asinches) -> std::string
219 return asinches ? (internal::str(width * POINT_TO_INCHES) +
"in," + internal::str(height * POINT_TO_INCHES) +
"in") : (internal::str(width) +
"," + internal::str(height));
223 inline auto rgb(std::string color) -> std::string {
return "rgb '" + color +
"'"; }
226 inline auto rgb(
int hexcolor) -> std::string {
return "rgb " + internal::str(hexcolor); }
232 static auto deg(
long val) -> std::string {
return internal::str(val) +
"deg"; }
235 static auto rad(
double val) -> std::string {
return internal::str(val); }
238 static auto pi(
double val) -> std::string {
return internal::str(val) +
"pi"; }
242 template <
typename... Args>
243 auto writedataset(std::ostream& out, std::size_t index,
const Args&... args) -> std::ostream&
246 out <<
"#==============================================================================" << std::endl;
247 out <<
"# DATASET #" << index << std::endl;
248 out <<
"#==============================================================================" << std::endl;
250 internal::write(out, args...);
257 inline auto palettecmd(std::ostream& out, std::string palette) -> std::ostream&
259 out <<
"#==============================================================================" << std::endl;
260 out <<
"# GNUPLOT-palette (" << palette <<
")" << std::endl;
261 out <<
"#------------------------------------------------------------------------------" << std::endl;
262 out <<
"# see more at https://github.com/Gnuplotting/gnuplot-palettes" << std::endl;
263 out <<
"#==============================================================================" << std::endl;
264 out << palettes.at(palette) << std::endl;
269 inline auto unsetpalettecmd(std::ostream& out) -> std::ostream&
271 out <<
"do for [i=1:20] { unset style line i }" << std::endl;
276 inline auto showterminalcmd(std::ostream& out, std::string size, std::string font, std::string title) -> std::ostream&
278 out <<
"#==============================================================================" << std::endl;
279 out <<
"# TERMINAL" << std::endl;
280 out <<
"#==============================================================================" << std::endl;
286 out <<
"set termoption enhanced" << std::endl;
287 if (font.size()) out <<
"set termoption " << font << std::endl;
288 out <<
"set terminal GNUTERM size " << size << (!title.empty() ?
" title '" + title +
"' " :
"") << std::endl;
289 out <<
"set encoding utf8" << std::endl;
294 inline auto saveterminalcmd(std::ostream& out, std::string extension, std::string size, std::string font) -> std::ostream&
296 out <<
"#==============================================================================" << std::endl;
297 out <<
"# TERMINAL" << std::endl;
298 out <<
"#==============================================================================" << std::endl;
299 out <<
"set terminal " << extension <<
" size " << size <<
" enhanced rounded " << font << std::endl;
300 out <<
"set encoding utf8" << std::endl;
305 inline auto outputcmd(std::ostream& out, std::string filename) -> std::ostream&
307 out <<
"#==============================================================================" << std::endl;
308 out <<
"# OUTPUT" << std::endl;
309 out <<
"#==============================================================================" << std::endl;
310 out <<
"set output '" << filename <<
"'" << std::endl;
311 out <<
"set encoding utf8" << std::endl;
316 inline auto multiplotcmd(std::ostream& out, std::size_t rows, std::size_t columns, std::string title) -> std::ostream&
318 out <<
"#==============================================================================" << std::endl;
319 out <<
"# MULTIPLOT" << std::endl;
320 out <<
"#==============================================================================" << std::endl;
321 out <<
"set multiplot";
322 if (rows != 0 || columns != 0)
324 out <<
" layout " << rows <<
"," << columns;
332 out <<
" title '" << title <<
"'";
341 inline auto runscript(std::string scriptfilename,
bool persistent) ->
bool
343 std::string command = persistent ?
"gnuplot -persistent " :
"gnuplot ";
344 command +=
"\"" + scriptfilename +
"\"";
345 return std::system(command.c_str()) == 0;
350 inline auto cleanpath(std::string path) -> std::string
352 const std::string invalidchars =
":*?!\"<>|";
353 std::string result = path;
354 result.erase(std::remove_if(result.begin(), result.end(), [&invalidchars](
char c)
355 { return (std::find(invalidchars.cbegin(), invalidchars.cend(), c) != invalidchars.cend()); }),