diff --git a/3rdparty/tiff/Makefile b/3rdparty/tiff/Makefile
index 782ae1100..6eae5c95f 100644
--- a/3rdparty/tiff/Makefile
+++ b/3rdparty/tiff/Makefile
@@ -2,7 +2,7 @@ ifeq ($(strip $(PREFIX)),)
override PREFIX = $(abspath $(CURDIR)/../build)
endif
-VERSION = 4.5.1
+VERSION = 4.7.0
TIFF_EXTRA_CONFIGURE_FLAGS ?=
ifeq ($(shell uname),Darwin)
TIFF_EXTRA_CONFIGURE_FLAGS += CFLAGS=-mmacosx-version-min=10.15
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 522c23cab..c79ec66b1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,6 +42,7 @@ set(GR_DIRECTORY
CACHE STRING "Default value for GRDIR"
)
option(GR_BUILD_DEMOS "Build demos for GR" OFF)
+option(GR_BUILD_GKSM "Build GKS metafile reader for GR" OFF)
option(GR_INSTALL "Create installation target for GR" ON)
option(GR_USE_BUNDLED_LIBRARIES "Use thirdparty libraries bundled with GR" OFF)
option(GR_MANUAL_MOC_AND_RCC "Manually run moc and rcc instead of relying on AUTOMOC and AUTORCC" OFF)
@@ -1243,6 +1244,8 @@ if((Qt6Widgets_FOUND
lib/grm/grplot/gredit/Bounding_logic.cpp
lib/grm/grplot/gredit/Bounding_object.cpp
lib/grm/grplot/gredit/CustomTreeWidgetItem.cpp
+ lib/grm/grplot/gredit/EditElementWidget.cpp
+ lib/grm/grplot/gredit/TableWidget.cpp
lib/grm/grplot/gredit/TreeWidget.cpp
lib/grm/grplot/grplot.cxx
lib/grm/grplot/grplot_mainwindow.cxx
@@ -1353,15 +1356,33 @@ if((Qt6Widgets_FOUND
${CMAKE_CURRENT_BINARY_DIR}/moc_AddElementWidget.cpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/AddElementWidget.h
)
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/moc_EditElementWidget.cpp
+ COMMAND
+ ${QT_MOC_EXECUTABLE} -DGRDIR=\"$(GR_DIRECTORY)\" ${MOC_INCLUDE_FLAGS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/EditElementWidget.h -o
+ ${CMAKE_CURRENT_BINARY_DIR}/moc_EditElementWidget.cpp
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/EditElementWidget.h
+ )
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/moc_TableWidget.cpp
+ COMMAND
+ ${QT_MOC_EXECUTABLE} -DGRDIR=\"$(GR_DIRECTORY)\" ${MOC_INCLUDE_FLAGS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/TableWidget.h -o
+ ${CMAKE_CURRENT_BINARY_DIR}/moc_TableWidget.cpp
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/TableWidget.h
+ )
target_sources(
grplot
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/moc_grplot_mainwindow.cxx
${CMAKE_CURRENT_BINARY_DIR}/moc_grplot_widget.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/moc_AddElementWidget.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_Bounding_logic.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_Bounding_object.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_CustomTreeWidgetItem.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/moc_EditElementWidget.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/moc_TableWidget.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_TreeWidget.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/moc_AddElementWidget.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_grm_args_t_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/moc_receiver_thread.cpp
)
@@ -1371,11 +1392,13 @@ if((Qt6Widgets_FOUND
grplot
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/grplot_mainwindow.hxx
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/grplot_widget.hxx
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/AddElementWidget.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/Bounding_logic.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/Bounding_object.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/CustomTreeWidgetItem.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/EditElementWidget.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/TableWidget.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/TreeWidget.h
- ${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/gredit/AddElementWidget.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/qtterm/grm_args_t_wrapper.h
${CMAKE_CURRENT_SOURCE_DIR}/lib/grm/grplot/qtterm/receiver_thread.h
)
@@ -1418,6 +1441,13 @@ if(GR_BUILD_DEMOS)
add_subdirectory(lib/grm/test/internal_api/grm grm_test_internal_api)
endif()
+if(GR_BUILD_GKSM)
+ add_executable(gksm lib/gks/gksm.c)
+ target_link_libraries(gksm PUBLIC gks_static)
+ target_compile_options(gksm PRIVATE ${COMPILER_OPTION_ERROR_IMPLICIT})
+ set_target_properties(gksm PROPERTIES C_STANDARD 90 C_EXTENSIONS OFF C_STANDARD_REQUIRED ON)
+endif()
+
if(GR_INSTALL)
install(FILES LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR}/)
install(
diff --git a/lib/gks/dl.c b/lib/gks/dl.c
index ac87aec1d..097293fdc 100644
--- a/lib/gks/dl.c
+++ b/lib/gks/dl.c
@@ -319,7 +319,8 @@ void gks_dl_write_item(gks_display_list_t *d, int fctid, int dx, int dy, int dim
COPY(f_arr_1, sizeof(double));
break;
- case 32: /* set character up vector */
+ case 32: /* set character up vector */
+ case 212: /* set clip sector */
len = 2 * sizeof(int) + 2 * sizeof(double);
if (d->nbytes + len > d->size) reallocate(d, len);
@@ -551,7 +552,7 @@ int gks_dl_read_item(char *dl, gks_state_list_t **gkss,
break;
case 32: /* set character up vector */
- case 252: /* move selection */
+ case 212: /* set clip sector */
RESOLVE(r1, double, sizeof(double));
RESOLVE(r2, double, sizeof(double));
break;
@@ -585,6 +586,11 @@ int gks_dl_read_item(char *dl, gks_state_list_t **gkss,
case 251: /* end selection */
break;
+
+ case 252: /* move selection */
+ RESOLVE(r1, double, sizeof(double));
+ RESOLVE(r2, double, sizeof(double));
+ break;
}
switch (*fctid)
@@ -696,6 +702,10 @@ int gks_dl_read_item(char *dl, gks_state_list_t **gkss,
case 211:
(*gkss)->clip_region = ia[0];
break;
+ case 212:
+ (*gkss)->clip_start_angle = r1[0];
+ (*gkss)->clip_end_angle = r2[0];
+ break;
}
fn(*fctid, *dx, *dy, *dimx, ia, 0, r1, 0, r2, *lc, chars, (void **)gkss);
diff --git a/lib/gks/error.c b/lib/gks/error.c
index 16f9a60cb..cee8fcc3c 100644
--- a/lib/gks/error.c
+++ b/lib/gks/error.c
@@ -278,6 +278,9 @@ const char *gks_function_name(int routine)
case 211:
name = "SET_CLIP_REGION";
break;
+ case 212:
+ name = "SET_CLIP_SECTOR";
+ break;
case 250:
name = "BEGIN_SELECTION";
break;
@@ -476,6 +479,9 @@ void gks_report_error(int routine, int errnum)
case 165:
message = "Clip region type is invalid in routine %s";
break;
+ case 166:
+ message = "Clip sector angles are invalid in routine %s";
+ break;
case 401:
message = "Dimensions of image are invalid in routine %s";
break;
diff --git a/lib/gks/gks.c b/lib/gks/gks.c
index e4dc71c66..23ba6c2ed 100644
--- a/lib/gks/gks.c
+++ b/lib/gks/gks.c
@@ -539,8 +539,10 @@ void gks_init_gks(void)
s->bwidth = 1;
s->bcoli = 0;
s->clip_tnr = 0;
- s->resize_behaviour = GKS_K_RESIZE;
s->clip_region = GKS_K_REGION_RECTANGLE;
+ s->clip_start_angle = 0;
+ s->clip_end_angle = 360;
+ s->resize_behaviour = GKS_K_RESIZE;
s->aspect_ratio = 1;
s->callback = NULL;
@@ -4556,6 +4558,35 @@ void gks_inq_clip_region(int *errind, int *region)
*region = s->clip_region;
}
+void gks_set_clip_sector(double start_angle, double end_angle)
+{
+ if (state >= GKS_K_GKOP)
+ {
+ if (start_angle >= 0 && end_angle > start_angle && end_angle <= 360)
+ {
+ s->clip_start_angle = f_arr_1[0] = start_angle;
+ s->clip_end_angle = f_arr_2[0] = end_angle;
+
+ /* call the device driver link routine */
+ gks_ddlk(SET_CLIP_SECTOR, 0, 0, 0, i_arr, 1, f_arr_1, 1, f_arr_2, 0, c_arr, NULL);
+ }
+ else
+ /* clip sector angles are invalid */
+ gks_report_error(SET_CLIP_SECTOR, 166);
+ }
+ else
+ /* GKS not in proper state. GKS must be in one of the states
+ GKOP, WSOP, WSAC or SGOP */
+ gks_report_error(SET_CLIP_SECTOR, 8);
+}
+
+void gks_inq_clip_sector(int *errind, double *start_angle, double *end_angle)
+{
+ *errind = GKS_K_NO_ERROR;
+ *start_angle = s->clip_start_angle;
+ *end_angle = s->clip_end_angle;
+}
+
void gks_set_resize_behaviour(int flag)
{
if (state >= GKS_K_GKOP)
diff --git a/lib/gks/gks.h b/lib/gks/gks.h
index c712a6c50..ea2e45009 100644
--- a/lib/gks/gks.h
+++ b/lib/gks/gks.h
@@ -709,6 +709,9 @@ DLLEXPORT void gks_inq_resize_behaviour(int *flag);
DLLEXPORT void gks_set_clip_region(int region);
DLLEXPORT void gks_inq_clip_region(int *errind, int *region);
+DLLEXPORT void gks_set_clip_sector(double start_angle, double end_angle);
+DLLEXPORT void gks_inq_clip_sector(int *errind, double *start_angle, double *end_angle);
+
/* Entry point definitions */
#define gsetlinecolorind gsetlinecolourind
diff --git a/lib/gks/gkscore.h b/lib/gks/gkscore.h
index e207de038..cb32f414c 100644
--- a/lib/gks/gkscore.h
+++ b/lib/gks/gkscore.h
@@ -116,6 +116,7 @@ extern "C" {
#define INQ_WS_STATE 209
#define SAMPLE_LOCATOR 210
#define SET_CLIP_REGION 211
+#define SET_CLIP_SECTOR 212
#define BEGIN_SELECTION 250
#define END_SELECTION 251
@@ -170,9 +171,10 @@ typedef struct
double bwidth;
int bcoli;
int clip_tnr;
+ int clip_region;
+ double clip_start_angle, clip_end_angle;
int resize_behaviour;
double aspect_ratio;
- int clip_region;
char *(*callback)(const char *);
int debug;
} gks_state_list_t;
diff --git a/lib/gks/mf.c b/lib/gks/mf.c
index 4dba5d6ea..ed35222a7 100644
--- a/lib/gks/mf.c
+++ b/lib/gks/mf.c
@@ -179,7 +179,8 @@ static void write_item(int fctid, int dx, int dy, int dimx, int *i_arr, int len_
COPY(f_arr_1, sizeof(double));
break;
- case 32: /* set character up vector */
+ case 32: /* set character up vector */
+ case 212: /* set clip sector */
len = 2 * sizeof(int) + 2 * sizeof(double);
if (p->nbytes + len > p->size) reallocate(len);
@@ -389,6 +390,7 @@ void gks_drv_mo(int fctid, int dx, int dy, int dimx, int *i_arr, int len_farr_1,
case 207:
case 208:
case 211:
+ case 212:
if (p->state == GKS_K_WS_ACTIVE)
{
@@ -575,7 +577,8 @@ static void interp(char *str)
RESOLVE(f_arr_1, double, sizeof(double));
break;
- case 32: /* set character up vector */
+ case 32: /* set character up vector */
+ case 212: /* set clip sector */
RESOLVE(f_arr_1, double, sizeof(double));
RESOLVE(f_arr_2, double, sizeof(double));
@@ -760,6 +763,9 @@ static void interp(char *str)
case 211:
gks_set_clip_region(i_arr[0]);
break;
+ case 212:
+ gks_set_clip_sector(f_arr_1[0], f_arr_2[0]);
+ break;
}
RESOLVE(len, int, sizeof(int));
diff --git a/lib/gks/pdf.c b/lib/gks/pdf.c
index fc8301dd9..bba517e5f 100644
--- a/lib/gks/pdf.c
+++ b/lib/gks/pdf.c
@@ -880,29 +880,89 @@ static void open_ws(int fd, int wstype)
pdf_open(fd);
}
-static void set_clip(double *clrt)
+static void arc(double x, double y, double w, double h, double a1, double a2)
+{
+ double bcp, cos_a1, cos_a2, sin_a1, sin_a2;
+
+ a1 = a1 * M_PI / 180;
+ a2 = a2 * M_PI / 180;
+
+ bcp = (4.0 / 3 * (1 - cos(0.5 * (a2 - a1))) / sin(0.5 * (a2 - a1)));
+
+ sin_a1 = sin(a1);
+ sin_a2 = sin(a2);
+ cos_a1 = cos(a1);
+ cos_a2 = cos(a2);
+
+ pdf_printf(p->content, "%.2f %.2f %.2f %.2f %.2f %.2f c\n", x + w * (cos_a1 - bcp * sin_a1),
+ y + h * (sin_a1 + bcp * cos_a1), x + w * (cos_a2 + bcp * sin_a2), y + h * (sin_a2 - bcp * cos_a2),
+ x + w * cos_a2, y + h * sin_a2);
+}
+
+static void draw_arc(double x, double y, double w, double h, double a1, double a2)
+{
+ if (a1 == a2) return;
+
+ while (fabs(a2 - a1) > 90 + 0.1)
+ {
+ if (a2 > a1)
+ {
+ arc(x, y, w, h, a1, a1 + 90);
+ a1 += 90;
+ }
+ else
+ {
+ arc(x, y, w, h, a1, a1 - 90);
+ a1 -= 90;
+ }
+ }
+
+ if (a1 != a2) arc(x, y, w, h, a1, a2);
+}
+
+static void set_clip_rect(int tnr)
{
- double x0, x1, y0, y1;
+ double *clrt, x0, x1, y0, y1;
int curve, i;
double x, y, xr, yr;
+ if (gkss->clip_tnr != 0)
+ clrt = gkss->viewport[gkss->clip_tnr];
+ else if (gkss->clip == GKS_K_CLIP)
+ clrt = gkss->viewport[tnr];
+ else
+ clrt = gkss->viewport[0];
+
NDC_to_DC(clrt[0], clrt[2], x0, y0);
NDC_to_DC(clrt[1], clrt[3], x1, y1);
- if (gkss->clip_region == GKS_K_REGION_ELLIPSE && (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP))
+ if (gkss->clip_region == GKS_K_REGION_ELLIPSE)
{
x = 0.5 * (x0 + x1);
y = 0.5 * (y0 + y1);
xr = 0.5 * (x1 - x0);
yr = 0.5 * (y1 - y0);
- pdf_moveto(p, x - xr * cx[3][2], y - yr * cy[3][2]);
- for (curve = 0; curve < 4; curve++)
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
+ {
+ double w, h;
+ w = xr;
+ h = yr;
+ pdf_moveto(p, x + w * cos(gkss->clip_start_angle * M_PI / 180),
+ y + h * sin(gkss->clip_start_angle * M_PI / 180));
+ draw_arc(x, y, w, h, gkss->clip_start_angle, gkss->clip_end_angle);
+ pdf_lineto(p, x, y);
+ }
+ else
{
- for (i = 0; i < 3; i++)
+ pdf_moveto(p, x - xr * cx[3][2], y - yr * cy[3][2]);
+ for (curve = 0; curve < 4; curve++)
{
- pdf_point(p, x - xr * cx[curve][i], y - yr * cy[curve][i]);
+ for (i = 0; i < 3; i++)
+ {
+ pdf_point(p, x - xr * cx[curve][i], y - yr * cy[curve][i]);
+ }
+ pdf_curveto(p);
}
- pdf_curveto(p);
}
}
else
@@ -1047,20 +1107,14 @@ static void polyline(int n, double *px, double *py)
set_transparency(p->alpha);
set_color(ln_color);
- if (gkss->clip_tnr != 0)
- {
- pdf_save(p);
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
+ pdf_save(p);
+ set_clip_rect(gkss->cntnr);
gks_set_dev_xform(gkss, p->window, p->viewport);
gks_emul_polyline(n, px, py, ln_type, gkss->cntnr, move, draw);
stroke();
- if (gkss->clip_tnr != 0)
- {
- pdf_restore(p);
- }
+ pdf_restore(p);
}
static void draw_marker(double xn, double yn, int mtype, double mscale, int mcolor)
@@ -1260,18 +1314,12 @@ static void polymarker(int n, double *px, double *py)
set_linetype(GKS_K_LINETYPE_SOLID, 1.0);
set_transparency(p->alpha);
- if (gkss->clip_tnr != 0)
- {
- pdf_save(p);
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
+ pdf_save(p);
+ set_clip_rect(gkss->cntnr);
marker_routine(n, px, py, mk_type, mk_size, mk_color);
- if (gkss->clip_tnr != 0)
- {
- pdf_restore(p);
- }
+ pdf_restore(p);
}
static void set_font(int font)
@@ -1391,11 +1439,8 @@ static void text(double px, double py, int nchars, char *chars)
if (tx_prec != GKS_K_TEXT_PRECISION_STROKE) set_font(tx_font);
- if (gkss->clip_tnr != 0)
- {
- pdf_save(p);
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
+ pdf_save(p);
+ set_clip_rect(gkss->cntnr);
if (tx_prec == GKS_K_TEXT_PRECISION_STRING)
{
@@ -1409,10 +1454,7 @@ static void text(double px, double py, int nchars, char *chars)
gks_emul_text(px, py, nchars, chars, line_routine, fill_routine);
}
- if (gkss->clip_tnr != 0)
- {
- pdf_restore(p);
- }
+ pdf_restore(p);
}
static void fill_routine(int n, double *px, double *py, int tnr)
@@ -1485,18 +1527,12 @@ static void fillarea(int n, double *px, double *py)
set_transparency(p->alpha);
set_color(fl_color);
- if (gkss->clip_tnr != 0)
- {
- pdf_save(p);
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
+ pdf_save(p);
+ set_clip_rect(gkss->cntnr);
line_routine(n, px, py, DrawBorder, gkss->cntnr);
- if (gkss->clip_tnr != 0)
- {
- pdf_restore(p);
- }
+ pdf_restore(p);
}
else if (fl_inter == GKS_K_INTSTYLE_SOLID)
{
@@ -1504,14 +1540,7 @@ static void fillarea(int n, double *px, double *py)
set_fillcolor(fl_color);
pdf_save(p);
- if (gkss->clip_tnr != 0)
- {
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
- else
- {
- set_clip(gkss->viewport[gkss->clip == GKS_K_CLIP ? gkss->cntnr : 0]);
- }
+ set_clip_rect(gkss->cntnr);
fill_routine(n, px, py, gkss->cntnr);
@@ -1527,14 +1556,7 @@ static void fillarea(int n, double *px, double *py)
p->pattern = fl_style;
pdf_save(p);
- if (gkss->clip_tnr != 0)
- {
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
- else
- {
- set_clip(gkss->viewport[gkss->clip == GKS_K_CLIP ? gkss->cntnr : 0]);
- }
+ set_clip_rect(gkss->cntnr);
fill_routine(n, px, py, gkss->cntnr);
@@ -1586,14 +1608,7 @@ static void cellarray(double xmin, double xmax, double ymin, double ymax, int dx
set_transparency(p->alpha);
pdf_save(p);
- if (gkss->clip_tnr != 0)
- {
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
- else
- {
- set_clip(gkss->viewport[gkss->clip == GKS_K_CLIP ? gkss->cntnr : 0]);
- }
+ set_clip_rect(gkss->cntnr);
have_alpha = 0;
if (true_color)
@@ -1727,46 +1742,6 @@ static void to_DC(int n, double *x, double *y)
}
}
-static void arc(double x, double y, double w, double h, double a1, double a2)
-{
- double bcp, cos_a1, cos_a2, sin_a1, sin_a2;
-
- a1 = a1 * M_PI / 180;
- a2 = a2 * M_PI / 180;
-
- bcp = (4.0 / 3 * (1 - cos(0.5 * (a2 - a1))) / sin(0.5 * (a2 - a1)));
-
- sin_a1 = sin(a1);
- sin_a2 = sin(a2);
- cos_a1 = cos(a1);
- cos_a2 = cos(a2);
-
- pdf_printf(p->content, "%.2f %.2f %.2f %.2f %.2f %.2f c\n", x + w * (cos_a1 - bcp * sin_a1),
- y + h * (sin_a1 + bcp * cos_a1), x + w * (cos_a2 + bcp * sin_a2), y + h * (sin_a2 - bcp * cos_a2),
- x + w * cos_a2, y + h * sin_a2);
-}
-
-static void draw_arc(double x, double y, double w, double h, double a1, double a2)
-{
- if (a1 == a2) return;
-
- while (fabs(a2 - a1) > 90)
- {
- if (a2 > a1)
- {
- arc(x, y, w, h, a1, a1 + 90);
- a1 += 90;
- }
- else
- {
- arc(x, y, w, h, a1, a1 - 90);
- a1 -= 90;
- }
- }
-
- if (a1 != a2) arc(x, y, w, h, a1, a2);
-}
-
static void draw_path(int n, double *px, double *py, int nc, int *codes)
{
int i, j;
@@ -2069,11 +2044,9 @@ static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
- if (gkss->clip_tnr != 0)
- {
- pdf_save(p);
- set_clip(gkss->viewport[gkss->clip_tnr]);
- }
+ pdf_save(p);
+ set_clip_rect(gkss->cntnr);
+
set_linetype(GKS_K_LINETYPE_SOLID, 1.0);
switch (primid)
{
@@ -2096,10 +2069,8 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
}
- if (gkss->clip_tnr != 0)
- {
- pdf_restore(p);
- }
+
+ pdf_restore(p);
}
#ifndef EMSCRIPTEN
diff --git a/lib/gks/plugin/cairoplugin.c b/lib/gks/plugin/cairoplugin.c
index 4f494e07f..b5715d2d7 100644
--- a/lib/gks/plugin/cairoplugin.c
+++ b/lib/gks/plugin/cairoplugin.c
@@ -816,30 +816,38 @@ static void set_clip_rect(int tnr)
cairo_reset_clip(p->cr);
- if (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP)
+ if (gkss->clip_tnr != 0)
+ tnr = gkss->clip_tnr;
+ else if (gkss->clip == GKS_K_NOCLIP)
+ tnr = 0;
+
+ x = p->rect[tnr][0][0];
+ y = p->rect[tnr][0][1];
+ w = p->rect[tnr][1][0] - p->rect[tnr][0][0];
+ h = p->rect[tnr][1][1] - p->rect[tnr][0][1];
+
+ if (gkss->clip_region == GKS_K_REGION_ELLIPSE)
{
- if (gkss->clip_tnr != 0)
- {
- tnr = gkss->clip_tnr;
- }
- x = p->rect[tnr][0][0];
- y = p->rect[tnr][0][1];
- w = p->rect[tnr][1][0] - p->rect[tnr][0][0];
- h = p->rect[tnr][1][1] - p->rect[tnr][0][1];
- if (gkss->clip_region == GKS_K_REGION_ELLIPSE)
+ cairo_save(p->cr);
+ cairo_translate(p->cr, x + 0.5 * w, y + 0.5 * h);
+ cairo_scale(p->cr, 1., h / w);
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
{
- cairo_save(p->cr);
- cairo_translate(p->cr, x + 0.5 * w, y + 0.5 * h);
- cairo_scale(p->cr, 1., h / w);
- cairo_arc(p->cr, 0., 0., w * 0.5, 0, 2 * M_PI);
- cairo_restore(p->cr);
+ cairo_move_to(p->cr, 0, 0);
+ cairo_arc_negative(p->cr, 0, 0, w * 0.5, -gkss->clip_start_angle * M_PI / 180,
+ -gkss->clip_end_angle * M_PI / 180);
}
else
{
- cairo_rectangle(p->cr, x, y, w, h);
+ cairo_arc(p->cr, 0., 0., w * 0.5, 0, 2 * M_PI);
}
- cairo_clip(p->cr);
+ cairo_restore(p->cr);
+ }
+ else
+ {
+ cairo_rectangle(p->cr, x, y, w, h);
}
+ cairo_clip(p->cr);
}
static void set_clipping(int index)
diff --git a/lib/gks/plugin/gsplugin.c b/lib/gks/plugin/gsplugin.c
index c29108718..28916e769 100644
--- a/lib/gks/plugin/gsplugin.c
+++ b/lib/gks/plugin/gsplugin.c
@@ -852,14 +852,16 @@ static void set_clip(double *clrt)
if (gkss->clip_region == GKS_K_REGION_ELLIPSE && (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP))
{
- int x, y, rx, ry;
+ double x, y, rx, ry;
- x = (int)(0.5 * (cx1 + cx2) + 0.5);
- y = (int)(0.5 * (cy1 + cy2) + 0.5);
- rx = (int)(0.5 * (cx2 - cx1) + 1);
- ry = (int)(0.5 * (cy2 - cy1) + 1);
+ x = 0.5 * (cx1 + cx2);
+ y = 0.5 * (cy1 + cy2);
+ rx = 0.5 * (cx2 - cx1);
+ ry = 0.5 * (cy2 - cy1);
- snprintf(buffer, 120, "np %d %d %d %d 0 360 ellipse clip", x, y, rx, ry);
+ snprintf(buffer, 120, "np %.2f %.2f m %.2f %.2f l %.2f %.2f %.2f %.2f %.2f %.2f ellipse clip", x, y,
+ x + rx * cos(gkss->clip_start_angle * M_PI / 180), y + ry * sin(gkss->clip_start_angle * M_PI / 180), x,
+ y, rx, ry, gkss->clip_start_angle, gkss->clip_end_angle);
}
else
{
diff --git a/lib/gks/plugin/pgfplugin.c b/lib/gks/plugin/pgfplugin.c
index 3ecab50ac..d49b730f8 100644
--- a/lib/gks/plugin/pgfplugin.c
+++ b/lib/gks/plugin/pgfplugin.c
@@ -921,10 +921,18 @@ static void set_clip_rect(int tnr)
y = (p->rect[tnr][0][1] + p->rect[tnr][1][1]) / 2;
w = p->rect[tnr][1][0] - p->rect[tnr][0][0];
h = p->rect[tnr][1][1] - p->rect[tnr][0][1];
- pgf_printf(p->stream,
- "\\begin{scope}\n"
- "\\clip (%f,%f) ellipse (%f and %f);\n",
- x, y, w / 2, h / 2);
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
+ pgf_printf(p->stream,
+ "\\begin{scope}\n"
+ "\\clip (%f,%f) arc (%f:%f:%f and %f) -- (%f,%f);\n",
+ x + 0.5 * w * cos(-gkss->clip_start_angle * M_PI / 180),
+ y + 0.5 * h * sin(-gkss->clip_start_angle * M_PI / 180), -gkss->clip_start_angle,
+ -gkss->clip_end_angle, w / 2, h / 2, x, y);
+ else
+ pgf_printf(p->stream,
+ "\\begin{scope}\n"
+ "\\clip (%f,%f) ellipse (%f and %f);\n",
+ x, y, w / 2, h / 2);
}
else
{
diff --git a/lib/gks/plugin/qtplugin_impl.cxx b/lib/gks/plugin/qtplugin_impl.cxx
index d45d6b6cf..1182be0d2 100644
--- a/lib/gks/plugin/qtplugin_impl.cxx
+++ b/lib/gks/plugin/qtplugin_impl.cxx
@@ -304,23 +304,26 @@ static void seg_xform_rel(double *x, double *y)
static void set_clip_rect(int tnr)
{
- if (gkss->clip_region == GKS_K_REGION_ELLIPSE)
+ if (gkss->clip_tnr != 0)
+ tnr = gkss->clip_tnr;
+ else if (gkss->clip == GKS_K_NOCLIP)
+ tnr = 0;
+
+ if (gkss->clip_region == GKS_K_REGION_ELLIPSE && tnr != 0)
{
- if (gkss->clip_tnr != 0)
- p->painter->setClipRegion(QRegion(p->rect[gkss->clip_tnr].toRect(), QRegion::Ellipse));
- else if (gkss->clip == GKS_K_CLIP)
- p->painter->setClipRegion(QRegion(p->rect[tnr].toRect(), QRegion::Ellipse));
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
+ {
+ QPainterPath path;
+ path.moveTo(p->rect[tnr].center());
+ path.arcTo(p->rect[tnr].toRect(), gkss->clip_start_angle, gkss->clip_end_angle - gkss->clip_start_angle);
+ p->painter->setClipPath(path);
+ }
else
- p->painter->setClipRect(p->rect[0]);
+ p->painter->setClipRegion(QRegion(p->rect[tnr].toRect(), QRegion::Ellipse));
}
else
{
- if (gkss->clip_tnr != 0)
- p->painter->setClipRect(p->rect[gkss->clip_tnr]);
- else if (gkss->clip == GKS_K_CLIP)
- p->painter->setClipRect(p->rect[tnr]);
- else
- p->painter->setClipRect(p->rect[0]);
+ p->painter->setClipRect(p->rect[tnr]);
}
}
diff --git a/lib/gks/plugin/svgplugin.c b/lib/gks/plugin/svgplugin.c
index 7a373444a..d05036702 100644
--- a/lib/gks/plugin/svgplugin.c
+++ b/lib/gks/plugin/svgplugin.c
@@ -1468,6 +1468,24 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
}
}
+static void svg_arc_path(double x, double y, double rx, double ry, double start_angle, double end_angle)
+{
+ double a1, a2;
+ double start_x, start_y, end_x, end_y;
+ int sweep_flag;
+
+ a1 = -start_angle * M_PI / 180;
+ a2 = -end_angle * M_PI / 180;
+ start_x = x + rx * cos(a2);
+ start_y = y + ry * sin(a2);
+ end_x = x + rx * cos(a1);
+ end_y = y + ry * sin(a1);
+ sweep_flag = end_angle - start_angle <= 180 ? 0 : 1;
+
+ svg_printf(p->stream, "", x, y, start_x, start_y, rx, ry,
+ sweep_flag, end_x, end_y);
+}
+
static void set_clip_path(int tnr)
{
double *vp;
@@ -1517,11 +1535,21 @@ static void set_clip_path(int tnr)
p->cr[p->clip_index].region = gkss->clip_region;
p->rect_index = p->clip_index;
if (gkss->clip_region == GKS_K_REGION_ELLIPSE && (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP))
- svg_printf(p->stream,
- "\n \n \n \n\n",
- path_id, p->rect_index, x + width / 2, y + height / 2, width / 2, height / 2);
+ {
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
+ {
+ svg_printf(p->stream, "\n \n", path_id, p->rect_index);
+ svg_arc_path(x + width / 2, y + height / 2, width / 2, height / 2, gkss->clip_start_angle,
+ gkss->clip_end_angle);
+ svg_printf(p->stream, " \n\n");
+ }
+ else
+ svg_printf(p->stream,
+ "\n \n \n"
+ " \n\n",
+ path_id, p->rect_index, x + width / 2, y + height / 2, width / 2, height / 2);
+ }
else
svg_printf(p->stream,
"\n \n clip_region == GKS_K_REGION_ELLIPSE && (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP))
{
- int x, y, rx, ry;
+ double x, y, rx, ry;
- x = (int)(0.5 * (cx1 + cx2) + 0.5);
- y = (int)(0.5 * (cy1 + cy2) + 0.5);
- rx = (int)(0.5 * (cx2 - cx1) + 1);
- ry = (int)(0.5 * (cy2 - cy1) + 1);
+ x = 0.5 * (cx1 + cx2);
+ y = 0.5 * (cy1 + cy2);
+ rx = 0.5 * (cx2 - cx1);
+ ry = 0.5 * (cy2 - cy1);
- snprintf(buffer, 120, "np %d %d %d %d 0 360 ellipse clip", x, y, rx, ry);
+ snprintf(buffer, 120, "np %.2f %.2f m %.2f %.2f l %.2f %.2f %.2f %.2f %.2f %.2f ellipse clip", x, y,
+ x + rx * cos(gkss->clip_start_angle * M_PI / 180), y + ry * sin(gkss->clip_start_angle * M_PI / 180), x,
+ y, rx, ry, gkss->clip_start_angle, gkss->clip_end_angle);
}
else
{
diff --git a/lib/gks/quartz/GKSView.m b/lib/gks/quartz/GKSView.m
index 41fef59e8..36b097576 100644
--- a/lib/gks/quartz/GKSView.m
+++ b/lib/gks/quartz/GKSView.m
@@ -345,7 +345,8 @@ - (void)interp:(char *)str
RESOLVE(f_arr_1, double, sizeof(double));
break;
- case 32: /* set character up vector */
+ case 32: /* set character up vector */
+ case 212: /* set clip sector */
RESOLVE(f_arr_1, double, sizeof(double));
RESOLVE(f_arr_2, double, sizeof(double));
break;
@@ -637,6 +638,11 @@ - (void)interp:(char *)str
case 211:
gkss->clip_region = i_arr[0];
break;
+
+ case 212:
+ gkss->clip_start_angle = f_arr_1[0];
+ gkss->clip_end_angle = f_arr_2[0];
+ break;
}
RESOLVE(len, int, sizeof(int));
@@ -1133,8 +1139,33 @@ static void begin_context(CGContextRef context)
if (gkss->clip_region == GKS_K_REGION_ELLIPSE && (gkss->clip_tnr != 0 || gkss->clip == GKS_K_CLIP))
{
CGMutablePathRef path = CGPathCreateMutable();
- CGPathAddEllipseInRect(path, NULL, clipRect);
- CGContextAddPath(context, path);
+ if (gkss->clip_start_angle > 0 || gkss->clip_end_angle < 360)
+ {
+ double a1, a2, x, y, start_x, start_y, end_x, end_y, w, h;
+
+ a1 = gkss->clip_start_angle * M_PI / 180;
+ a2 = gkss->clip_end_angle * M_PI / 180;
+ w = clipRect.size.width;
+ h = clipRect.size.height;
+ x = clipRect.origin.x + w * 0.5;
+ y = clipRect.origin.y + h * 0.5;
+ start_x = x + w * cos(a1);
+ start_y = y + h * sin(a1);
+ end_x = x + w * cos(a2);
+ end_y = y + h * sin(a2);
+
+ CGAffineTransform m = CGAffineTransformMakeTranslation(x, y);
+ m = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, h / w), m);
+ CGPathAddArc(path, &m, 0, 0, 0.5 * w, a1, a2, a1 > a2);
+ CGPathAddLineToPoint(path, &m, 0, 0);
+ CGContextAddPath(context, path);
+ CGContextClosePath(context);
+ }
+ else
+ {
+ CGPathAddEllipseInRect(path, NULL, clipRect);
+ CGContextAddPath(context, path);
+ }
CGContextClip(context);
CGPathRelease(path);
}
diff --git a/lib/gr/gr.c b/lib/gr/gr.c
index ea4e8f13e..c6def61f8 100644
--- a/lib/gr/gr.c
+++ b/lib/gr/gr.c
@@ -172,14 +172,16 @@ typedef struct
int ints;
int styli;
int facoli;
+ int clip;
int tnr;
double wn[4], vp[4];
int scale_options;
double bwidth;
int bcoli;
int clip_tnr;
- int resize_behaviour;
int clip_region;
+ double clip_start_angle, clip_end_angle;
+ int resize_behaviour;
double alpha;
double txoff[2];
} state_list;
@@ -5577,9 +5579,9 @@ static void draw_axis(char which, axis_t *axis, int pass)
void gr_drawaxis(char which, axis_t *axis)
{
- int errind, tnr, ltype, clsw, halign, valign;
+ int errind, tnr, ltype, clsw;
double wn[4], vp[4], clrt[4];
- int i, pass;
+ int pass;
check_autoinit;
@@ -5610,7 +5612,7 @@ void gr_drawaxis(char which, axis_t *axis)
static void draw_axis_grid(char which, axis_t *axis, int pass)
{
int errind, tnr, color;
- double wn[4], vp[4], width;
+ double wn[4], vp[4], width, alpha;
int i;
/* inquire current normalization transformation */
@@ -5618,10 +5620,11 @@ static void draw_axis_grid(char which, axis_t *axis, int pass)
gks_inq_current_xformno(&errind, &tnr);
gks_inq_xform(tnr, &errind, wn, vp);
- /* save line width and line color */
+ /* save line width, line color and transparency */
gks_inq_pline_linewidth(&errind, &width);
gks_inq_pline_color_index(&errind, &color);
+ gks_inq_transparency(&errind, &alpha);
gks_inq_pline_color_index(&errind, &color);
@@ -5629,10 +5632,10 @@ static void draw_axis_grid(char which, axis_t *axis, int pass)
{
if (axis->ticks[i].is_major == pass)
{
- if (color != 0)
- gks_set_pline_color_index(axis->ticks[i].is_major ? 88 : 90);
+ if (color != 1)
+ gks_set_transparency(axis->ticks[i].is_major ? alpha * 0.4 : alpha * 0.2);
else
- gks_set_pline_linewidth(axis->ticks[i].is_major ? 2.0 : 1.0);
+ gks_set_pline_color_index(axis->ticks[i].is_major ? 88 : 90);
if (which == 'X')
{
@@ -5649,17 +5652,17 @@ static void draw_axis_grid(char which, axis_t *axis, int pass)
}
}
- /* restore line width and line color */
+ /* restore line width, line color and transparency */
gks_set_pline_linewidth(width);
gks_set_pline_color_index(color);
+ gks_set_transparency(alpha);
}
void gr_drawaxes(axis_t *x_axis, axis_t *y_axis, int options)
{
int errind, tnr, ltype, clsw;
double wn[4], vp[4], clrt[4];
- double tick, minor_tick, major_tick;
int pass;
axis_t axis;
@@ -5752,12 +5755,12 @@ void gr_freeaxis(axis_t *axis)
}
}
-static void grid_line(double x0, double y0, double x1, double y1, int color, int major)
+static void grid_line(double x0, double y0, double x1, double y1, int color, double alpha, int major)
{
- if (color != 0)
- gks_set_pline_color_index(major ? 88 : 90);
+ if (color != 1)
+ gks_set_transparency(major ? alpha * 0.4 : alpha * 0.2);
else
- gks_set_pline_linewidth(major ? 2.0 : 1.0);
+ gks_set_pline_color_index(major ? 88 : 90);
start_pline(x0, y0);
pline(x1, y1);
@@ -5791,7 +5794,7 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
{
int errind, tnr;
int ltype, color, clsw, major;
- double width;
+ double width, alpha;
double clrt[4], wn[4], vp[4];
double x_min, x_max, y_min, y_max, feps;
@@ -5818,11 +5821,12 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
y_min = wn[2];
y_max = wn[3];
- /* save linetype, line width, line color and clipping indicator */
+ /* save linetype, line width, line color, transparency and clipping indicator */
gks_inq_pline_linetype(&errind, <ype);
gks_inq_pline_linewidth(&errind, &width);
gks_inq_pline_color_index(&errind, &color);
+ gks_inq_transparency(&errind, &alpha);
gks_inq_clip(&errind, &clsw, clrt);
gks_set_pline_linetype(GKS_K_LINETYPE_SOLID);
@@ -5848,7 +5852,7 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
major = i == 0 ? 1 : 0;
if (yi != y_min)
{
- if (pass == major) grid_line(x_min, yi, x_max, yi, color, major);
+ if (pass == major) grid_line(x_min, yi, x_max, yi, color, alpha, major);
}
}
@@ -5881,7 +5885,7 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
else
major = 0;
- if (pass == major) grid_line(x_min, yi, x_max, yi, color, major);
+ if (pass == major) grid_line(x_min, yi, x_max, yi, color, alpha, major);
i++;
yi = y_org + i * y_tick;
@@ -5907,7 +5911,7 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
major = i == 0 ? 1 : 0;
if (xi != x_min)
{
- if (pass == major) grid_line(xi, y_min, xi, y_max, color, major);
+ if (pass == major) grid_line(xi, y_min, xi, y_max, color, alpha, major);
}
}
@@ -5940,7 +5944,7 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
else
major = 0;
- if (pass == major) grid_line(xi, y_min, xi, y_max, color, major);
+ if (pass == major) grid_line(xi, y_min, xi, y_max, color, alpha, major);
i++;
xi = x_org + i * x_tick;
@@ -5949,11 +5953,12 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
}
}
- /* restore linetype, line width, line color and clipping indicator */
+ /* restore linetype, line width, line color, transparency and clipping indicator */
gks_set_pline_linetype(ltype);
gks_set_pline_linewidth(width);
gks_set_pline_color_index(color);
+ gks_set_transparency(alpha);
gks_set_clipping(clsw);
if (flag_stream)
@@ -5962,12 +5967,13 @@ void gr_grid(double x_tick, double y_tick, double x_org, double y_org, int major
x_tick, y_tick, x_org, y_org, major_x, major_y);
}
-static void grid_line3d(double x0, double y0, double z0, double x1, double y1, double z1, int color, int major)
+static void grid_line3d(double x0, double y0, double z0, double x1, double y1, double z1, int color, double alpha,
+ int major)
{
- if (color != 0)
- gks_set_pline_color_index(major ? 88 : 90);
+ if (color != 1)
+ gks_set_transparency(major ? alpha * 0.4 : alpha * 0.2);
else
- gks_set_pline_linewidth(major ? 2.0 : 1.0);
+ gks_set_pline_color_index(major ? 88 : 90);
start_pline3d(x0, y0, z0);
pline3d(x1, y1, z1);
@@ -6012,7 +6018,7 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
int modern_projection_type;
int ltype, color, clsw, major;
- double width;
+ double width, alpha;
double x_min = 0, x_max = 0, y_min = 0, y_max = 0, z_min = 0, z_max = 0;
@@ -6064,11 +6070,12 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
z_max = wx.zmax;
}
- /* save linetype, line width, line color and clipping indicator */
+ /* save linetype, line width, line color, transparency and clipping indicator */
gks_inq_pline_linetype(&errind, <ype);
gks_inq_pline_linewidth(&errind, &width);
gks_inq_pline_color_index(&errind, &color);
+ gks_inq_transparency(&errind, &alpha);
gks_inq_clip(&errind, &clsw, clrt);
gks_set_pline_linetype(GKS_K_LINETYPE_SOLID);
@@ -6092,8 +6099,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
major = i == 0;
if (fabs(zi - z_min) > FEPS * zi)
{
- grid_line3d(x_org, y_min, zi, x_org, y_max, zi, color, major);
- grid_line3d(x_min, y_org, zi, x_max, y_org, zi, color, major);
+ grid_line3d(x_org, y_min, zi, x_org, y_max, zi, color, alpha, major);
+ grid_line3d(x_min, y_org, zi, x_max, y_org, zi, color, alpha, major);
}
}
@@ -6127,8 +6134,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
if (fabs(zi - z_min) > FEPS * zi)
{
- grid_line3d(x_org, y_min, zi, x_org, y_max, zi, color, major);
- grid_line3d(x_min, y_org, zi, x_max, y_org, zi, color, major);
+ grid_line3d(x_org, y_min, zi, x_org, y_max, zi, color, alpha, major);
+ grid_line3d(x_min, y_org, zi, x_max, y_org, zi, color, alpha, major);
}
i++;
@@ -6155,8 +6162,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
major = i == 0;
if (fabs(yi - y_min) > FEPS * yi)
{
- grid_line3d(x_min, yi, z_org, x_max, yi, z_org, color, major);
- grid_line3d(x_org, yi, z_min, x_org, yi, z_max, color, major);
+ grid_line3d(x_min, yi, z_org, x_max, yi, z_org, color, alpha, major);
+ grid_line3d(x_org, yi, z_min, x_org, yi, z_max, color, alpha, major);
}
}
@@ -6190,8 +6197,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
if (fabs(yi - y_min) > FEPS * yi)
{
- grid_line3d(x_min, yi, z_org, x_max, yi, z_org, color, major);
- grid_line3d(x_org, yi, z_min, x_org, yi, z_max, color, major);
+ grid_line3d(x_min, yi, z_org, x_max, yi, z_org, color, alpha, major);
+ grid_line3d(x_org, yi, z_min, x_org, yi, z_max, color, alpha, major);
}
i++;
@@ -6218,8 +6225,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
major = i == 0;
if (fabs(xi - x_min) > FEPS * xi)
{
- grid_line3d(xi, y_min, z_org, xi, y_max, z_org, color, major);
- grid_line3d(xi, y_org, z_min, xi, y_org, z_max, color, major);
+ grid_line3d(xi, y_min, z_org, xi, y_max, z_org, color, alpha, major);
+ grid_line3d(xi, y_org, z_min, xi, y_org, z_max, color, alpha, major);
}
}
@@ -6253,8 +6260,8 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
if (fabs(xi - x_min) > FEPS * xi)
{
- grid_line3d(xi, y_min, z_org, xi, y_max, z_org, color, major);
- grid_line3d(xi, y_org, z_min, xi, y_org, z_max, color, major);
+ grid_line3d(xi, y_min, z_org, xi, y_max, z_org, color, alpha, major);
+ grid_line3d(xi, y_org, z_min, xi, y_org, z_max, color, alpha, major);
}
i++;
@@ -6263,11 +6270,12 @@ void gr_grid3d(double x_tick, double y_tick, double z_tick, double x_org, double
}
}
- /* restore linetype, line width, line color and clipping indicator */
+ /* restore linetype, line width, line color, transparency and clipping indicator */
gks_set_pline_linetype(ltype);
gks_set_pline_linewidth(width);
gks_set_pline_color_index(color);
+ gks_set_transparency(alpha);
gks_set_clipping(clsw);
if (flag_stream)
@@ -9302,7 +9310,7 @@ void gr_surface(int nx, int ny, double *px, double *py, double *pz, int option)
gks_set_fill_color_index(color);
}
- gks_select_xform(MODERN_NDC);
+ if (modern_projection_type) gks_select_xform(MODERN_NDC);
np = 4;
gks_fillarea(np, xn, yn);
@@ -9313,7 +9321,7 @@ void gr_surface(int nx, int ny, double *px, double *py, double *pz, int option)
gks_polyline(np, xn, yn);
}
- gks_select_xform(tnr);
+ if (modern_projection_type) gks_select_xform(tnr);
}
j--;
@@ -9830,7 +9838,7 @@ static void rebin(int nx, int ny, double *px, double *py, double *pz, int *nxq,
void gr_contour(int nx, int ny, int nh, double *px, double *py, double *h, double *pz, int major_h)
{
int i, j;
- int errind, tnr, ltype, color, halign, valign;
+ int errind, ltype, color, halign, valign;
double chux, chuy;
int nxq, nyq;
double *xq = NULL, *yq = NULL, *zq = NULL;
@@ -12030,7 +12038,7 @@ static void latex2image(char *string, int pointSize, double *rgb, int *width, in
rename(png, path);
if (remove(tex) != 0 || remove(dvi) != 0)
{
- fprintf(stderr, "error deleting temprorary files\n");
+ fprintf(stderr, "error deleting temporary files\n");
}
}
else
@@ -12947,6 +12955,7 @@ void gr_savestate(void)
{
int errind;
state_list *s = NULL;
+ double clrt[4];
check_autoinit;
@@ -12976,6 +12985,7 @@ void gr_savestate(void)
gks_inq_fill_color_index(&errind, &s->facoli);
gks_inq_transparency(&errind, &s->alpha);
+ gks_inq_clip(&errind, &s->clip, clrt);
gks_inq_current_xformno(&errind, &s->tnr);
gks_inq_xform(WC, &errind, s->wn, s->vp);
@@ -12984,8 +12994,9 @@ void gr_savestate(void)
gks_inq_border_width(&errind, &s->bwidth);
gks_inq_border_color_index(&errind, &s->bcoli);
gks_inq_clip_xform(&errind, &s->clip_tnr);
- gks_inq_resize_behaviour(&s->resize_behaviour);
gks_inq_clip_region(&errind, &s->clip_region);
+ gks_inq_clip_sector(&errind, &s->clip_start_angle, &s->clip_end_angle);
+ gks_inq_resize_behaviour(&s->resize_behaviour);
s->txoff[0] = txoff[0];
s->txoff[1] = txoff[1];
@@ -13026,6 +13037,7 @@ void gr_restorestate(void)
gks_set_fill_color_index(s->facoli);
gks_set_transparency(s->alpha);
+ gks_set_clipping(s->clip);
gks_select_xform(s->tnr);
gks_set_window(WC, s->wn[0], s->wn[1], s->wn[2], s->wn[3]);
gks_set_window(MODERN_NDC, -1, 1, -1, 1);
@@ -13041,8 +13053,9 @@ void gr_restorestate(void)
gks_set_border_width(s->bwidth);
gks_set_border_color_index(s->bcoli);
gks_select_clip_xform(s->clip_tnr);
- gks_set_resize_behaviour(s->resize_behaviour);
gks_set_clip_region(s->clip_region);
+ gks_set_clip_sector(s->clip_start_angle, s->clip_end_angle);
+ gks_set_resize_behaviour(s->resize_behaviour);
s->txoff[0] = txoff[0];
s->txoff[1] = txoff[1];
@@ -13070,6 +13083,7 @@ void gr_restorestate(void)
ctx->styli = s->styli;
ctx->facoli = s->facoli;
+ ctx->clip = s->clip;
ctx->tnr = s->tnr;
ctx->wn[0] = s->wn[0];
ctx->wn[2] = s->wn[2];
@@ -13085,8 +13099,10 @@ void gr_restorestate(void)
ctx->bwidth = s->bwidth;
ctx->bcoli = s->bcoli;
ctx->clip_tnr = s->clip_tnr;
- ctx->resize_behaviour = s->resize_behaviour;
ctx->clip_region = s->clip_region;
+ ctx->clip_start_angle = s->clip_start_angle;
+ ctx->clip_end_angle = s->clip_end_angle;
+ ctx->resize_behaviour = s->resize_behaviour;
ctx->txoff[0] = s->txoff[0];
ctx->txoff[1] = s->txoff[1];
@@ -13157,6 +13173,7 @@ void gr_selectcontext(int context)
ctx->facoli = 1;
ctx->alpha = 1.0;
+ ctx->clip = GKS_K_NOCLIP;
ctx->tnr = WC;
ctx->wn[0] = ctx->wn[2] = 0;
ctx->wn[1] = ctx->wn[3] = 1;
@@ -13168,8 +13185,10 @@ void gr_selectcontext(int context)
ctx->bwidth = 1;
ctx->bcoli = 1;
ctx->clip_tnr = 0;
- ctx->resize_behaviour = GKS_K_RESIZE;
ctx->clip_region = GKS_K_REGION_RECTANGLE;
+ ctx->clip_start_angle = 0;
+ ctx->clip_end_angle = 360;
+ ctx->resize_behaviour = GKS_K_RESIZE;
ctx->txoff[0] = 0;
ctx->txoff[1] = 0;
@@ -13198,6 +13217,7 @@ void gr_selectcontext(int context)
gks_set_fill_color_index(ctx->facoli);
gks_set_transparency(ctx->alpha);
+ gks_set_clipping(ctx->clip);
gks_select_xform(ctx->tnr);
gks_set_window(WC, ctx->wn[0], ctx->wn[1], ctx->wn[2], ctx->wn[3]);
gks_set_window(MODERN_NDC, -1, 1, -1, 1);
@@ -13213,8 +13233,9 @@ void gr_selectcontext(int context)
gks_set_border_width(ctx->bwidth);
gks_set_border_color_index(ctx->bcoli);
gks_select_clip_xform(ctx->clip_tnr);
- gks_set_resize_behaviour(ctx->resize_behaviour);
gks_set_clip_region(ctx->clip_region);
+ gks_set_clip_sector(ctx->clip_start_angle, ctx->clip_end_angle);
+ gks_set_resize_behaviour(ctx->resize_behaviour);
txoff[0] = ctx->txoff[0];
txoff[1] = ctx->txoff[1];
@@ -13230,6 +13251,7 @@ void gr_savecontext(int context)
{
int errind;
int id;
+ double clrt[4];
check_autoinit;
@@ -13283,6 +13305,7 @@ void gr_savecontext(int context)
gks_inq_fill_color_index(&errind, &app_context->buf[id]->facoli);
gks_inq_transparency(&errind, &app_context->buf[id]->alpha);
+ gks_inq_clip(&errind, &app_context->buf[id]->clip, clrt);
gks_inq_current_xformno(&errind, &app_context->buf[id]->tnr);
gks_inq_xform(WC, &errind, app_context->buf[id]->wn, app_context->buf[id]->vp);
@@ -13291,8 +13314,9 @@ void gr_savecontext(int context)
gks_inq_border_width(&errind, &app_context->buf[id]->bwidth);
gks_inq_border_color_index(&errind, &app_context->buf[id]->bcoli);
gks_inq_clip_xform(&errind, &app_context->buf[id]->clip_tnr);
- gks_inq_resize_behaviour(&app_context->buf[id]->resize_behaviour);
gks_inq_clip_region(&errind, &app_context->buf[id]->clip_region);
+ gks_inq_clip_sector(&errind, &app_context->buf[id]->clip_start_angle, &app_context->buf[id]->clip_end_angle);
+ gks_inq_resize_behaviour(&app_context->buf[id]->resize_behaviour);
app_context->buf[id]->txoff[0] = txoff[0];
app_context->buf[id]->txoff[1] = txoff[1];
@@ -13307,6 +13331,7 @@ void gr_destroycontext(int context)
{
int errind;
int id;
+ double clrt[4];
check_autoinit;
@@ -13360,6 +13385,7 @@ void gr_destroycontext(int context)
gks_inq_fill_color_index(&errind, &app_context->buf[id]->facoli);
gks_inq_transparency(&errind, &app_context->buf[id]->alpha);
+ gks_inq_clip(&errind, &app_context->buf[id]->clip, clrt);
gks_inq_current_xformno(&errind, &app_context->buf[id]->tnr);
gks_inq_xform(WC, &errind, app_context->buf[id]->wn, app_context->buf[id]->vp);
@@ -13368,8 +13394,9 @@ void gr_destroycontext(int context)
gks_inq_border_width(&errind, &app_context->buf[id]->bwidth);
gks_inq_border_color_index(&errind, &app_context->buf[id]->bcoli);
gks_inq_clip_xform(&errind, &app_context->buf[id]->clip_tnr);
- gks_inq_resize_behaviour(&app_context->buf[id]->resize_behaviour);
gks_inq_clip_region(&errind, &app_context->buf[id]->clip_region);
+ gks_inq_clip_sector(&errind, &app_context->buf[id]->clip_start_angle, &app_context->buf[id]->clip_end_angle);
+ gks_inq_resize_behaviour(&app_context->buf[id]->resize_behaviour);
app_context->buf[id]->txoff[0] = txoff[0];
app_context->buf[id]->txoff[1] = txoff[1];
@@ -14566,6 +14593,29 @@ void gr_inqclipregion(int *region)
gks_inq_clip_region(&errind, region);
}
+void gr_setclipsector(double start_angle, double end_angle)
+{
+ check_autoinit;
+
+ gks_set_clip_sector(start_angle, end_angle);
+ if (ctx)
+ {
+ ctx->clip_start_angle = start_angle;
+ ctx->clip_end_angle = end_angle;
+ }
+
+ if (flag_stream) gr_writestream("\n", start_angle, end_angle);
+}
+
+void gr_inqclipsector(double *start_angle, double *end_angle)
+{
+ int errind;
+
+ check_autoinit;
+
+ gks_inq_clip_sector(&errind, start_angle, end_angle);
+}
+
void gr_settextoffset(double xoff, double yoff)
{
check_autoinit;
diff --git a/lib/gr/gr.h b/lib/gr/gr.h
index a435d6ff2..fa64a62c8 100644
--- a/lib/gr/gr.h
+++ b/lib/gr/gr.h
@@ -67,14 +67,14 @@ typedef enum
GR_OPTION_Z_LOG2 = 1u << 8u,
GR_OPTION_X_LN = 1u << 9u,
GR_OPTION_Y_LN = 1u << 10u,
- GR_OPTION_Z_LN = 1u << 11u,
+ GR_OPTION_Z_LN = 1u << 11u
} scale_option_t;
typedef enum
{
GR_SPEC_LINE = 1u << 0u,
GR_SPEC_MARKER = 1u << 1u,
- GR_SPEC_COLOR = 1u << 2u,
+ GR_SPEC_COLOR = 1u << 2u
} linespec_t;
typedef enum
@@ -86,7 +86,7 @@ typedef enum
GR_OPTION_COLORED_MESH,
GR_OPTION_CELL_ARRAY,
GR_OPTION_SHADED_MESH,
- GR_OPTION_3D_MESH, /* for GR3 */
+ GR_OPTION_3D_MESH /* for GR3 */
} surface_option_t;
typedef enum
@@ -102,7 +102,7 @@ typedef enum
GR_LINETO,
GR_CURVE3,
GR_CURVE4,
- GR_CLOSEPOLY = 0x4f,
+ GR_CLOSEPOLY = 0x4f
} path_code_t;
typedef enum
@@ -112,7 +112,7 @@ typedef enum
GR_XFORM_LOG,
GR_XFORM_LOGLOG,
GR_XFORM_CUBIC,
- GR_XFORM_EQUALIZED,
+ GR_XFORM_EQUALIZED
} xform_types_t;
typedef enum
@@ -120,7 +120,7 @@ typedef enum
GR_INTERP2_NEAREST,
GR_INTERP2_LINEAR,
GR_INTERP2_SPLINE,
- GR_INTERP2_CUBIC,
+ GR_INTERP2_CUBIC
} interp2_method_t;
typedef struct
@@ -446,6 +446,8 @@ DLLEXPORT void gr_setmathfont(int font);
DLLEXPORT void gr_inqmathfont(int *font);
DLLEXPORT void gr_setclipregion(int region);
DLLEXPORT void gr_inqclipregion(int *region);
+DLLEXPORT void gr_setclipsector(double start_angle, double end_angle);
+DLLEXPORT void gr_inqclipsector(double *start_angle, double *end_angle);
DLLEXPORT void gr_settextoffset(double xoff, double yoff);
DLLEXPORT char *gr_ftoa(char *string, double value, format_reference_t *reference);
DLLEXPORT void gr_getformat(format_reference_t *result, double origin, double min, double max, double tick_width,
diff --git a/lib/gr/import.c b/lib/gr/import.c
index 6e818e806..dc16ac245 100644
--- a/lib/gr/import.c
+++ b/lib/gr/import.c
@@ -68,6 +68,7 @@ static char *format[] = {
"setcharup:ff",
"setclip:i",
"setclipregion:i",
+ "setclipsector:ff",
"setcolormap:i",
"setcolorrep:ifff",
"setfillcolorind:i",
@@ -443,154 +444,157 @@ static void gr(int id)
gr_setclipregion(i_arg[0]);
break;
case 48:
- gr_setcolormap(i_arg[0]);
+ gr_setclipsector(f_arg[0], f_arg[1]);
break;
case 49:
- gr_setcolorrep(i_arg[0], f_arg[0], f_arg[1], f_arg[2]);
+ gr_setcolormap(i_arg[0]);
break;
case 50:
- gr_setfillcolorind(i_arg[0]);
+ gr_setcolorrep(i_arg[0], f_arg[0], f_arg[1], f_arg[2]);
break;
case 51:
- gr_setfillintstyle(i_arg[0]);
+ gr_setfillcolorind(i_arg[0]);
break;
case 52:
- gr_setfillstyle(i_arg[0]);
+ gr_setfillintstyle(i_arg[0]);
break;
case 53:
- gr_setlinecolorind(i_arg[0]);
+ gr_setfillstyle(i_arg[0]);
break;
case 54:
- gr_setlinetype(i_arg[0]);
+ gr_setlinecolorind(i_arg[0]);
break;
case 55:
- gr_setlinewidth(f_arg[0]);
+ gr_setlinetype(i_arg[0]);
break;
case 56:
- gr_setmarkercolorind(i_arg[0]);
+ gr_setlinewidth(f_arg[0]);
break;
case 57:
- gr_setmarkersize(f_arg[0]);
+ gr_setmarkercolorind(i_arg[0]);
break;
case 58:
- gr_setmarkertype(i_arg[0]);
+ gr_setmarkersize(f_arg[0]);
break;
case 59:
- gr_setmathfont(i_arg[0]);
+ gr_setmarkertype(i_arg[0]);
break;
case 60:
- gr_setorthographicprojection(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
+ gr_setmathfont(i_arg[0]);
break;
case 61:
- gr_setperspectiveprojection(f_arg[0], f_arg[1], f_arg[2]);
+ gr_setorthographicprojection(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
break;
case 62:
- gr_setpicturesizeforvolume(i_arg[0], i_arg[1]);
+ gr_setperspectiveprojection(f_arg[0], f_arg[1], f_arg[2]);
break;
case 63:
- gr_setprojectiontype(i_arg[0]);
+ gr_setpicturesizeforvolume(i_arg[0], i_arg[1]);
break;
case 64:
- gr_setresizebehaviour(i_arg[0]);
+ gr_setprojectiontype(i_arg[0]);
break;
case 65:
- gr_setscale(i_arg[0]);
+ gr_setresizebehaviour(i_arg[0]);
break;
case 66:
- gr_setscalefactors3d(f_arg[0], f_arg[1], f_arg[2]);
+ gr_setscale(i_arg[0]);
break;
case 67:
- gr_setspace(f_arg[0], f_arg[1], i_arg[0], i_arg[1]);
+ gr_setscalefactors3d(f_arg[0], f_arg[1], f_arg[2]);
break;
case 68:
- gr_setspace3d(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
+ gr_setspace(f_arg[0], f_arg[1], i_arg[0], i_arg[1]);
break;
case 69:
- gr_settextalign(i_arg[0], i_arg[1]);
+ gr_setspace3d(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 70:
- gr_settextcolorind(i_arg[0]);
+ gr_settextalign(i_arg[0], i_arg[1]);
break;
case 71:
- gr_settextencoding(i_arg[0]);
+ gr_settextcolorind(i_arg[0]);
break;
case 72:
- gr_settextfontprec(i_arg[0], i_arg[1]);
+ gr_settextencoding(i_arg[0]);
break;
case 73:
- gr_settextoffset(f_arg[0], f_arg[1]);
+ gr_settextfontprec(i_arg[0], i_arg[1]);
break;
case 74:
- gr_settextpath(i_arg[0]);
+ gr_settextoffset(f_arg[0], f_arg[1]);
break;
case 75:
- gr_setthreadnumber(i_arg[0]);
+ gr_settextpath(i_arg[0]);
break;
case 76:
- gr_settitles3d(s_arg[0], s_arg[1], s_arg[2]);
+ gr_setthreadnumber(i_arg[0]);
break;
case 77:
+ gr_settitles3d(s_arg[0], s_arg[1], s_arg[2]);
+ break;
+ case 78:
gr_settransformationparameters(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5], f_arg[6], f_arg[7],
f_arg[8]);
break;
- case 78:
+ case 79:
gr_settransparency(f_arg[0]);
break;
- case 79:
+ case 80:
gr_setviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
- case 80:
+ case 81:
gr_setvolumebordercalculation(i_arg[0]);
break;
- case 81:
+ case 82:
gr_setwindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
- case 82:
+ case 83:
gr_setwindow3d(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
break;
- case 83:
+ case 84:
gr_setwsviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
- case 84:
+ case 85:
gr_setwswindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
- case 85:
+ case 86:
gr_shadelines(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
break;
- case 86:
+ case 87:
gr_shadepoints(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
break;
- case 87:
+ case 88:
gr_spline(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2]);
break;
- case 88:
+ case 89:
gr_surface(i_arg[0], i_arg[1], f_arr[0], f_arr[1], f_arr[2], i_arg[2]);
break;
- case 89:
+ case 90:
gr_text(f_arg[0], f_arg[1], s_arg[0]);
break;
- case 90:
+ case 91:
gr_textext(f_arg[0], f_arg[1], s_arg[0]);
break;
- case 91:
+ case 92:
gr_textx(f_arg[0], f_arg[1], s_arg[0], i_arg[0]);
break;
- case 92:
+ case 93:
gr_titles3d(s_arg[0], s_arg[1], s_arg[2]);
break;
- case 93:
+ case 94:
gr_tricontour(i_arg[0], f_arr[0], f_arr[1], f_arr[2], i_arg[2], f_arr[3]);
break;
- case 94:
+ case 95:
gr_trisurface(i_arg[0], f_arr[0], f_arr[1], f_arr[2]);
break;
- case 95:
+ case 96:
gr_unselectcontext();
break;
- case 96:
+ case 97:
gr_uselinespec(s_arg[0]);
break;
- case 97:
+ case 98:
gr_verrorbars(i_arg[0], f_arr[0], f_arr[1], f_arr[2], f_arr[3]);
break;
}
diff --git a/lib/grm/grplot/README.md b/lib/grm/grplot/README.md
index 427d79fe4..b574fb730 100644
--- a/lib/grm/grplot/README.md
+++ b/lib/grm/grplot/README.md
@@ -9,7 +9,7 @@ This program allows to create plots from the command line while using simple key
The following parameters are key-value pairs which can be used for every plot type.
- `file`: contains the data which should be displayed. If no file is referred this results in an error message. If this parameter is the first argument the `file` keyword may be omitted. More information about these files can be found under the subchapter `Data file`. A hyphen '-' in place of a file path normally means "read from standard input". Since 'grplot' does not read from standard input by default, use '-' to redirect the input. This way 'grplot' can be used in a pipe.
-- `kind`: defines the plot type that should be displayed. Possible options are: `barplot`, `contour`, `contourf`, `heatmap`, `hexbin`, `hist`, `imshow`, `isosurface`, `line`, `marginal_heatmap`, `polar`, `polar_histogram`, `polar_heatmap`, `pie`, `plot3`, `scale`, `scatter`, `scatter3`, `shade`, `surface`, `stairs`, `stem`, `tricontour`, `trisurface`, `quiver`, `volume`, `wireframe`. The default plot type is `line`.
+- `kind`: defines the plot type that should be displayed. Possible options are: `barplot`, `contour`, `contourf`, `heatmap`, `hexbin`, `hist`, `imshow`, `isosurface`, `line`, `marginal_heatmap`, `polar_heatmap`, `polar_histogram`, `polar_line`, `polar_scatter`, `pie`, `plot3`, `scale`, `scatter`, `scatter3`, `shade`, `surface`, `stairs`, `stem`, `tricontour`, `trisurface`, `quiver`, `volume`, `wireframe`. The default plot type is `line`.
To get extra information about a specific plot type use:
@@ -22,11 +22,11 @@ The following parameters are key-value pairs which can be used for every plot ty
There is another parameter that can be used for all two-dimensional data sets:
- `keep_aspect_ratio` or `aspect`: defines whether the aspect ratio of the initial picture is kept or not. Possible values for this parameter are 0 or 1.
-- `only_quadratic_aspect_ratio`: defines whether the aspect ratio of quadratic data (x, y) is forced to be quadratic and kept this way or not. Notice this parameter will not work when the `keep_aspect_ratio` parameter has the value of 0. Possible values for this parameter are 0 or 1.
+- `only_quadratic_aspect_ratio`: defines whether the aspect ratio of quadratic data (x, y) is forced to be quadratic and kept this way or not. Notice this parameter will not work if the `keep_aspect_ratio` parameter has the value of 0. Possible values for this parameter are 0 or 1.
For plots where multiple columns are read there is also a parameter that allows to select columns.
-- `columns`: define the columns of the file which should be respected in the plot. The default is all columns. If all columns from x to y should be drawn use `x:y`. The `y` is necessary even when all lines from `x` to the end should be drawn. To select more than 1 specific column use the `,` without whitespace as separator.
+- `columns`: define the columns of the file which should be respected in the plot. The default is all columns. If all columns from x to y should be drawn use `x:y`. The `y` is necessary even if all lines from `x` to the end should be drawn. To select more than 1 specific column use the `,` without whitespace as separator.
For one-dimensional data sets there are also options to define if inside the data-file there are not just y- and maybe error-values included. These parameters are similar to the previous `column` parameter and can also be used in combination with it.
@@ -35,9 +35,9 @@ For one-dimensional data sets there are also options to define if inside the dat
- `error_columns`: define the columns of the file which should represent the error-data. Depending on the status of the flag parameter `equal_up_and_down_error` this parameter must include either one or two columns for each y-column which should have error bars later. If this parameter is used and includes enough columns it is not needed to set `error` to enable the error bars. It can still be set to edit the resulting error bars.
- `xye_file`: defines a special case of the data-file. In this case the first column represents the x-, the second the y- and the third and maybe fourth column the error-values. The parameter can only have the values 0 and 1. If this parameter has the value 1 it is not needed to set `error` to enable the error bars. It can still be set to edit the resulting error bars.
-There are more key-value parameters. These parameters only effect specific plot types. For example `bar_width` only makes sense, when bars are drawn. All possible parameters are:
+There are more key-value parameters. These parameters only effect specific plot types. For example `bar_width` only makes sense, if bars are drawn. All possible parameters are:
-`accelerate`, `algorithm`, `bar_color`, `bar_width`, `bin_counts`, `bin_edges`, `c`, `colormap`, `draw_edges`, `edge_color`, `edge_width`, `grplot`, `int_lim`, `isovalue`, `kind`, `levels`, `line_spec`, `major_h`, `marginal_heatmap_kind`, `marker_type`, `num_bins`, `normalization`, `orientation`, `phi_flip`, `rotation`, `scatter_z`, `stairs`, `step_where`, `style`, `tilt`, `transformation`, `x_bins`, `x_colormap`, `x_flip`, `y_bins`, `y_colormap`, `y_flip`, `y_labels`
+`accelerate`, `algorithm`, `bar_color`, `bar_width`, `bin_counts`, `bin_edges`, `c`, `clip_negative`, `colormap`, `draw_edges`, `edge_color`, `edge_width`, `error_bar_style`, `grplot`, `int_lim`, `isovalue`, `keep_radii_axes`, `kind`, `levels`, `line_spec`, `major_h`, `marginal_heatmap_kind`, `marker_type`, `num_bins`, `normalization`, `orientation`, `phi_flip`, `rotation`, `scatter_z`, `stairs`, `step_where`, `style`, `tilt`, `transformation`, `x_bins`, `x_colormap`, `x_flip`, `y_bins`, `y_colormap`, `y_flip`, `y_labels`
All parameters are separated by a blank. Some parameters are more complex than others. These parameters represent a container inside GRM.
@@ -72,7 +72,7 @@ This is an advanced example for a command line, where container parameters are s
../../../../lib/grm/grplot/data/test.dat kind:barplot ind_edge_width:2,{{indices:2},{width:5.0},{indices:1},{width:8.0}} error:{error_bar_color:4}
```
-If wanted the plot can be exported as a `pdf`, `png`, `jpeg` or `svg` file using the interactive menu. Alternatively these files can directly be created from console line when the environment variable `GKS_WSTYPE` is set.
+If wanted the plot can be exported as a `pdf`, `png`, `jpeg` or `svg` file using the interactive menu. Alternatively these files can directly be created from console line if the environment variable `GKS_WSTYPE` is set.
## Test
@@ -96,7 +96,7 @@ Valid keys are:
1. `title`: sets the title of the plot
2. `x_label`, `y_label`, `z_label`: set the label for the respective axis
-3. `resample_method`: defines how the data is resampled when needed
+3. `resample_method`: defines how the data is resampled if needed
4. `location`: defines where the legend should be drawn
5. `x_log`, `y_log`, `z_log`: defines whether the respective axis is plotted logarithmic. These options only work if the data respects the definition of the logarithmic function.
6. `x_grid`, `y_grid`, `z_grid`: defines the grid for the respective axis
@@ -112,15 +112,15 @@ The next line after the header may contain the column labels. If the data does n
2. `line`, `scatter`: One or more columns are expected here. Each column will be displayed in a single plot. The values inside the columns gets therefore interpreted as y-values. In combination with the `error` parameter every 2nd (and 3rd) column gets interpreted as error-values. More information are found by the `error` parameter itself. There is also another option which allows the user to define which columns include the x-, y- and error-values. For this the parameters `x_columns`, `y_columns` and `error_columns` can be used.
3. `isosurface`, `volume`: The expected data are multiple matrices. Each matrix represents a slice inside the volume.
4. `plot3`, `scatter`, `scatter3`, `tricontour`, `trisurface`: Three columns with data are expected, representing the x-, y- and z-data.
-5. `barplot`, `hist`, `stem`, `stairs`: One column is expected which represents the y-data. In combination with the `error` parameter the 2nd (and 3rd) column gets interpreted as error-values. More information are found by the `error` parameter itself. There is also another option which allows the user to define which column include the x-, y- and error-values. For this the parameters `x_columns`, `y_columns` and `error_columns` can be used. For these kinds only one column for x and y is expected.
+5. `barplot`, `hist`, `stem`, `stairs`: One or more columns are expected. Each column will be displayed in a single plot. The values inside the columns gets therefore interpreted as y-values. In combination with the `error` parameter the 2nd (and 3rd) column gets interpreted as error-values. More information are found by the `error` parameter itself. There is also another option which allows the user to define which column include the x-, y- and error-values. For this the parameters `x_columns`, `y_columns` and `error_columns` can be used.
6. `pie`: The expected data are 1-4 lines. The first line represents the data which should be displayed. The next 3 rows are used to set the RGB of the pie charts. Each row stands for one RGB element.
7. `polar_histogram`: One column is expected which represents the values.
-8. `polar`: The expected data are two columns containing the angles and values.
-9. `polar_heatmap`: The expected data is a matrix. Each element of the matrix is displayed according to its position inside the matrix. These elements are interpreted as values in theta- and phi-direction. When not given, theta will be in the range of 0.0 and 3.0 while phi will be in range of 0.0 and 360.0. Both parameters can be changed with `x_range` for theta and `y_range` for phi.
+8. `polar_line`, `polar_scatter`: The expected data are pairs of two columns containing the angles and values.
+9. `polar_heatmap`: The expected data is a matrix. Each element of the matrix is displayed according to its position inside the matrix. These elements are interpreted as values in theta- and phi-direction. If not given, theta will be in the range of 0.0 and 3.0 while phi will be in range of 0.0 and 360.0. Both parameters can be changed with `x_range` for theta and `y_range` for phi.
10. `quiver`: The expected data are two matrices. The first matrix contains the information about the x-directions and the second matrix the information about the y-directions.
11. `hexbin`, `shade`: The expected data are two columns, representing the x- and y-data.
-A plot type that expect the same data shape as other plot types can be converted using an interactive menu. The interaction also yields extra information about the plot, when the mouse is being hovered over them.
+A plot type that expect the same data shape as other plot types can be converted using an interactive menu. The interaction also yields extra information about the plot, if the mouse is being hovered over them.
## Editor
@@ -136,9 +136,9 @@ The expected data is one column representing the y-data.
Possible parameters for the bar plot are:
-1. `bar_color`: This parameter defines the color of all bars inside the plot except of those which are referred with `ind_bar_color`. The value of this parameter can either be an integer which represents a color index or three doubles which represent the RGB value of the color. When the parameter isn't set the bars will have the color with index 989 (dark blue).
+1. `bar_color`: This parameter defines the color of all bars inside the plot except of those which are referred with `ind_bar_color`. The value of this parameter can either be an integer which represents a color index or three doubles which represent the RGB value of the color. If the parameter isn't set the bars will have the color with index 989 (dark blue).
2. `bar_width`: This parameter defines the width of all bars inside the plot. Depending on the specified width the bars may overlap. The value of this parameter is a double number where its default is 0.8.
-3. `edge_color`: This parameter defines the color of all edges inside the plot except of those which are referred with `ind_edge_color`. The value of this parameter can either be an integer which represents a color index or three doubles which represents the RGB value of the color. When the parameter isn't set the edges will have the color with index 1 (black).
+3. `edge_color`: This parameter defines the color of all edges inside the plot except of those which are referred with `ind_edge_color`. The value of this parameter can either be an integer which represents a color index or three doubles which represents the RGB value of the color. If the parameter isn't set the edges will have the color with index 1 (black).
4. `edge_width`: This parameter defines the width of all edges inside the plot except those which are referred with `ind_edge_width`. The value of this parameter is a double number where its default is 1.0.
5. `error`: With this parameter the relative error of each bar can be displayed. The values for this parameter are key-value pairs with the following keys:
- `error_bar_color`: Defines the color of the error bars as an integer. If no color is given an error is raised.
@@ -149,33 +149,34 @@ Possible parameters for the bar plot are:
`error:{{error_bar_color:`color_index`},{downwards_cap_color:`color_index`},{upwards_cap_color:`color_index`}}`
-6. `ind_bar_color`: With this parameter the color of specific bars can be changed. The value of this parameter are key-value pairs with the following keys:
+6. `error_bar_style`: Defines how the error-bars are displayed. As single error-lines(0) or as an error-area(1).
+7. `ind_bar_color`: With this parameter the color of specific bars can be changed. The value of this parameter are key-value pairs with the following keys:
- `indices`: The index number of the bar, which color should be changed.
- `rgb`: The new color for the specified bar. The value has to be three doubles or integer which represents the RGB value.
The syntax of this parameter is:
`ind_bar_color:`number_of_bars`,{{indices:`first_bar_index`},{rgb:`r1,g1,b1`}`,...`}`
-7. `ind_edge_color`: With this parameter the color of specific edges can be changed. The value of this parameter are key-value pairs with the following keys:
+8. `ind_edge_color`: With this parameter the color of specific edges can be changed. The value of this parameter are key-value pairs with the following keys:
- `indices`: The index number of the edge, which color should be changed.
- `rgb`: The new color for the specified edge. The value has to be three doubles or integer which represents the RGB value.
The syntax of this parameter is:
`ind_edge_color:`number_of_edges`,{{indices:`first_edge_index`},{rgb:`r1,g1,b1`}`,...`}`
-8. `ind_edge_width`: With this parameter the width of specific edges can be changed. The value of this parameter are key-value pairs with the following keys:
+9. `ind_edge_width`: With this parameter the width of specific edges can be changed. The value of this parameter are key-value pairs with the following keys:
- `indices`: The index number of the edge, which width should be changed.
- `width`: The new width for the specified edge. The value of this parameter has to be an integer or double.
The syntax of this parameter is:
`ind_edge_width:`number_of_edges`,{{indices:`first_edge_index`},{width:`first_edge_width`}`,...`}`
-9. `orientation`: This parameter defines the orientation of the displayed bars. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
-10. `style`: This parameter defines how the data inside the bar plot is displayed. There are three options:
+10. `orientation`: This parameter defines the orientation of the displayed bars. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
+11. `style`: This parameter defines how the data inside the bar plot is displayed. There are three options:
- `default`: All values are displayed with a separate bar.
- `stacked`: The values are displayed with bars which are stacked over each other.
- `lined`: The values are displayed with smaller bars next to each other.
-11. `y_labels`: This parameter allows the user to set labels to specific bars, which can for example display the value of the bar. The syntax of this parameter is `y_labels:{`label1`,`label2`,`...`}`.
+12. `y_labels`: This parameter allows the user to set labels to specific bars, which can for example display the value of the bar. The syntax of this parameter is `y_labels:{`label1`,`label2`,`...`}`.
### CONTOUR
@@ -246,7 +247,9 @@ Possible parameters for the histogram are:
Note: If the error of the bars is to be displayed, the last two columns of the data are used for the error. If the up and down error are equal use `equal_up_and_down_error` with a value of `1`. In that case only one column is expected for the error data instead of the two. This parameter flag also does not need the `error` parameter to be set. Like by the `error` parameter some of the columns inside the data will get interpreted as error-values. The syntax of this parameter is:
`error:{{error_bar_color:`color_index`},{downwards_cap_color:`color_index`},{upwards_cap_color:`color_index`}}`
-5. `orientation`: This parameter defines the orientation of the displayed bars. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
+
+5. `error_bar_style`: Defines how the error-bars are displayed. As single error-lines(0) or as an error-area(1).
+6. `orientation`: This parameter defines the orientation of the displayed bars. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
### IMSHOW
@@ -257,7 +260,7 @@ The expected data is a matrix. Each element of the matrix is displayed according
Possible parameters for the imshow plot are:
1. `colormap` or `cmap`: This parameter defines the colormap to be used. The default is 44 (viridis).
-2. `grplot`: This parameter is there for the consistency between the plot types `contour`, `contourf`, `heatmap`, `imshow`, `marginal_heatmap`, `surface`, `wireframe`. When set the data is displayed in the same order by all of these types where in general the imshow plot would be flipped. The value can be either 0 or 1 where the value if not otherwise set is always 1.
+2. `grplot`: This parameter is there for the consistency between the plot types `contour`, `contourf`, `heatmap`, `imshow`, `marginal_heatmap`, `surface`, `wireframe`. If set the data is displayed in the same order by all of these types where in general the imshow plot would be flipped. The value can be either 0 or 1 where the value if not otherwise set is always 1.
3. `x_flip`: This parameter defines whether the x-axis is flipped or not.
4. `y_flip`: This parameter defines whether the y-axis is flipped or not.
@@ -282,7 +285,7 @@ The expected data are columns. Each column will be interpreted as a single line.
Possible parameters for the line plot are:
1. `error`: With this parameter the relative error of each line can be displayed. The value of this parameter are key-value pairs with the following keys:
- - `error_bar_color`: Defines the color of the error bars. The value of this parameter has to be an integer. When no color is given this leads to an error.
+ - `error_bar_color`: Defines the color of the error bars. The value of this parameter has to be an integer. If no color is given this leads to an error.
- `downwards_cap_color`: Defines the downwards cap color of the error bars. The value of this parameter has to be an integer.
- `upwards_cap_color`: Defines the upwards cap color of the error bars. The value of this parameter has to be an integer.
@@ -290,19 +293,20 @@ Possible parameters for the line plot are:
`error:{{error_bar_color:`color_index`},{downwards_cap_color:`color_index`},{upwards_cap_color:`color_index`}}`
-2. `int_limits_high`: This parameter defines the upper limits of all integrals.
+2. `error_bar_style`: Defines how the error-bars are displayed. As single error-lines(0) or as an error-area(1).
+3. `int_limits_high`: This parameter defines the upper limits of all integrals.
The syntax for this parameter is:
`int_limits_high:`number_of_elements`,`elem_1`,`elem_2`,`...
-3. `int_limits_low`: This parameter defines the lower limits of all integrals.
+4. `int_limits_low`: This parameter defines the lower limits of all integrals.
The syntax for this parameter is:
`int_limits_low:`number_of_elements`,`elem_1`,`elem_2`,`...
-4. `orientation`: This parameter defines the orientation of the displayed lines. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
+5. `orientation`: This parameter defines the orientation of the displayed lines. They can either be drawn `horizontal` or `vertical` while the default is `horizontal`.
### MARGINAL_HEATMAP
@@ -315,22 +319,16 @@ Possible parameters for the marginal heatmap are:
1. `algorithm`: This parameter defines whether the data is summed up or if the maximum to be used for the side plots. Possible values are `max` and `sum` where the default is `sum`.
2. `colormap` or `cmap`: This parameter defines the colormap to be used. The default is 44 (viridis).
3. `marginal_heatmap_kind` or `h_kind`: This parameter defines what part of the data is displayed inside the side plots. Possible options are:
- - `all`: When the kind is set to all, the side plots respect the complete data of the heatmap. This is the default case.
- - `line`: When the kind is set to line, the side plots respect only a specific row/column of the data.
+ - `all`: If the kind is set to all, the side plots respect the complete data of the heatmap. This is the default case.
+ - `line`: If the kind is set to line, the side plots respect only a specific row/column of the data.
4. `x_flip`: This parameter defines whether the x-axis is flipped or not.
5. `y_flip`: This parameter defines whether the y-axis is flipped or not.
-### POLAR
-
-This plot type converts the data into a polar plot. A polar plot displays a polyline in polar coordinates, with theta indicating the angle in radians and rho indicating the radius value for each point.
-
-The expected data are two columns containing the angles and values.
-
### POLAR_HEATMAP
This plot type converts the data into a polar heatmap. A polar heatmap is a heatmap in polar coordinates.
-The expected data is a matrix. Each element of the matrix is displayed according to its position inside the matrix. These elements are interpreted as values in phi- and theta-direction. When not given, theta will be in the range of 0.0 and 3.0 while phi will be in range of 0.0 and 360.0. Both parameters can be changed with `x_range` for phi and `y_range` for theta.
+The expected data is a matrix. Each element of the matrix is displayed according to its position inside the matrix. These elements are interpreted as values in phi- and theta-direction. If not given, theta will be in the range of 0.0 and 3.0 while phi will be in range of 0.0 and 360.0. Both parameters can be changed with `x_range` for phi and `y_range` for theta.
Possible parameters for the polar heatmap are:
@@ -347,15 +345,36 @@ Possible parameters for the polar histogram are:
1. `bin_counts`: This parameter sets the amount of classes without binning.
2. `bin_edges`: This parameter sets the borders of the classes.
3. `bin_width`: This parameter sets the width of all the bins.
-4. `draw_edges`: When a colormap is used this parameter decides whether the outer shape is drawn or not. The value can be either 0 or 1.
-5. `num_bins`: This parameter sets the number of classes which are respected during the binning.
-6. `normalization`: This parameter sets the type of normalization for the polar histogram. The value can be `count`, `probability`, `countdensity`, `pdf`, `cumcount` or `cdf`.
-7. `phi_flip`: This parameter decides whether the phi values are flipped or not. The value can be either 0 or 1.
-8. `stairs`: When this parameter is set, only the outer shapes of the bins are drawn. The value can be either 0 or 1.
-9. `x_colormap`: This parameter sets the colormap for the x-direction.
-10. `x_flip`: This parameter defines whether the x-axis is flipped or not.
-11. `y_colormap`: This parameter sets the colormap for the y-direction.
-12. `y_flip`: This parameter defines whether the y-axis is flipped or not.
+4. `draw_edges`: If a colormap is used this parameter decides whether the outer shape is drawn or not. The value can be either 0 or 1.
+5. `keep_radii_axes`: This parameter only have an impact, if `y_lim` is set. In that case the ranges for the radii axes from `y_lim` get ignored while the polar histogram still gets affected by the `y_lim`.
+6. `num_bins`: This parameter sets the number of classes which are respected during the binning.
+7. `normalization`: This parameter sets the type of normalization for the polar histogram. The value can be `count`, `probability`, `countdensity`, `pdf`, `cumcount` or `cdf`.
+8. `phi_flip`: This parameter decides whether the phi values are flipped or not. The value can be either 0 or 1.
+9. `stairs`: If this parameter is set, only the outer shapes of the bins are drawn. The value can be either 0 or 1.
+10. `x_colormap`: This parameter sets the colormap for the x-direction.
+11. `x_flip`: This parameter defines whether the x-axis is flipped or not.
+12. `y_colormap`: This parameter sets the colormap for the y-direction.
+13. `y_flip`: This parameter defines whether the y-axis is flipped or not.
+
+### POLAR_LINE
+
+This plot type converts the data into a polar plot/line-plot. A polar plot displays a polyline in polar coordinates, with theta indicating the angle in radians and rho indicating the radius value for each point.
+
+The expected data are two columns containing the angles and values.
+
+Possible parameters for the polar line plot are:
+
+1. `clip_negative`: If this parameter is set, only positive radii are displayed, otherwise negative will be mirrored
+
+### POLAR_SCATTER
+
+This plot type converts the data into a polar scatter plot. A polar scatter displays each data point as a point inside the polar coordinate system, with theta indicating the angle in radians and rho indicating the radius value for each point.
+
+The expected data are two columns containing the angles and values.
+
+Possible parameters for the polar scatter plot are:
+
+1. `clip_negative`: If this parameter is set, only positive radii are displayed, otherwise negative will be mirrored
### PIE
@@ -378,7 +397,7 @@ The expected data are columns. Each column will be interpreted as a single plot.
Possible parameters for the scatter plot are:
1. `error`: With this parameter the relative error of each line can be displayed. The value of this parameter are key-value pairs with the following keys:
- - `error_bar_color`: Defines the color of the error bars. The value of this parameter has to be an integer. When no color is given this leads to an error.
+ - `error_bar_color`: Defines the color of the error bars. The value of this parameter has to be an integer. If no color is given this leads to an error.
- `downwards_cap_color`: Defines the downwards cap color of the error bars. The value of this parameter has to be an integer.
- `upwards_cap_color`: Defines the upwards cap color of the error bars. The value of this parameter has to be an integer.
@@ -386,7 +405,8 @@ Possible parameters for the scatter plot are:
`error:{{error_bar_color:`color_index`},{downwards_cap_color:`color_index`},{upwards_cap_color:`color_index`}}`
-2. `marker_type`: This parameter defines the style of the visualized data points, where the effect belonging to the numbers is the same as for [gr_setmarkertype](https://gr-framework.org/c-gr.html?highlight=gr_setmarkertype#_CPPv416gr_setmarkertypei).
+2. `error_bar_style`: Defines how the error-bars are displayed. As single error-lines(0) or as an error-area(1).
+3. `marker_type`: This parameter defines the style of the visualized data points, where the effect belonging to the numbers is the same as for [gr_setmarkertype](https://gr-framework.org/c-gr.html?highlight=gr_setmarkertype#_CPPv416gr_setmarkertypei).
### SCATTER3
diff --git a/lib/grm/grplot/gredit/EditElementWidget.cpp b/lib/grm/grplot/gredit/EditElementWidget.cpp
new file mode 100644
index 000000000..64cb43712
--- /dev/null
+++ b/lib/grm/grplot/gredit/EditElementWidget.cpp
@@ -0,0 +1,420 @@
+#include "EditElementWidget.h"
+
+EditElementWidget::EditElementWidget(GRPlotWidget *widget, QWidget *parent) : QWidget(parent)
+{
+ grplot_widget = widget;
+#if !defined(NO_XERCES_C)
+ schema_tree = grplot_widget->get_schema_tree();
+#else
+ schema_tree = nullptr;
+#endif
+}
+
+void EditElementWidget::AttributeEditEvent()
+{
+ auto current_selection = grplot_widget->get_current_selection();
+ if (current_selection == nullptr) return;
+
+ if (this->layout() != nullptr)
+ {
+ QLayoutItem *item;
+ while ((item = this->layout()->takeAt(0)) != nullptr)
+ {
+ delete item->widget();
+ delete item;
+ }
+ delete this->layout();
+ fields.clear();
+ labels.clear();
+ attr_type.clear();
+ }
+
+ auto combo_box_attr = grplot_widget->getComboBoxAttributes();
+ auto check_box_attr = grplot_widget->getCheckBoxAttributes();
+ schema_tree = grplot_widget->get_schema_tree();
+
+ std::string currently_clicked_name = (*current_selection)->get_ref()->localName();
+ QString title("Selected: ");
+ title.append(currently_clicked_name.c_str());
+ this->setWindowTitle(title);
+ auto changeParametersLabel = new QLabel("Change Parameters:");
+ changeParametersLabel->setStyleSheet("font-weight: bold");
+ auto form = new QFormLayout;
+ form->addRow(changeParametersLabel);
+
+ QWidget *lineEdit;
+
+ std::vector sorted_names;
+ for (const auto &cur_attr_name : (*current_selection)->get_ref()->getAttributeNames())
+ {
+ sorted_names.push_back(cur_attr_name);
+ }
+ std::sort(sorted_names.begin(), sorted_names.end());
+ for (const auto &cur_attr_name : sorted_names)
+ {
+ if (util::startsWith(cur_attr_name, "_")) continue;
+ QString tooltipString =
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), cur_attr_name)[1].c_str();
+ tooltipString.append(". Default: ");
+ tooltipString.append(
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), cur_attr_name)[0].c_str());
+
+ if (combo_box_attr.contains(cur_attr_name.c_str()))
+ {
+ lineEdit = new QComboBox(this);
+ grplot_widget->advancedAttributeComboBoxHandler(cur_attr_name, (*current_selection)->get_ref()->localName(),
+ &lineEdit);
+ if ((*current_selection)->get_ref()->getAttribute(cur_attr_name).isInt())
+ {
+ attr_type.emplace(cur_attr_name, "xs:integer");
+ }
+ else if ((*current_selection)->get_ref()->getAttribute(cur_attr_name).isDouble())
+ {
+ attr_type.emplace(cur_attr_name, "xs:double");
+ }
+ else
+ {
+ attr_type.emplace(cur_attr_name, "xs:string");
+ }
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ }
+ else if (check_box_attr.contains(cur_attr_name.c_str()))
+ {
+ lineEdit = new QCheckBox(this);
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ ((QCheckBox *)lineEdit)
+ ->setChecked(static_cast((*current_selection)->get_ref()->getAttribute(cur_attr_name)) == 1);
+ }
+ else
+ {
+ if ((*current_selection)->get_ref()->getAttribute(cur_attr_name).isInt())
+ {
+ attr_type.emplace(cur_attr_name, "xs:integer");
+ }
+ else if ((*current_selection)->get_ref()->getAttribute(cur_attr_name).isDouble())
+ {
+ attr_type.emplace(cur_attr_name, "xs:double");
+ }
+ else
+ {
+ attr_type.emplace(cur_attr_name, "xs:string");
+ }
+ lineEdit = new QLineEdit(this);
+ ((QLineEdit *)lineEdit)
+ ->setText(static_cast((*current_selection)->get_ref()->getAttribute(cur_attr_name)).c_str());
+ ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
+ }
+ QString text_label = QString(cur_attr_name.c_str());
+ form->addRow(text_label, lineEdit);
+
+ labels << text_label;
+ fields << lineEdit;
+ }
+
+ if (schema_tree != nullptr)
+ {
+ std::shared_ptr element;
+ auto selections = schema_tree->querySelectorsAll("[name=" + currently_clicked_name + "]");
+ for (const auto &selection : selections)
+ {
+ if (selection->localName() == "xs:element") element = selection->children()[0];
+ }
+
+ /* iterate through complextype elements */
+ for (const auto &child : element->children())
+ {
+ if (child->localName() == "xs:attribute")
+ {
+ auto attr_name = static_cast(child->getAttribute("name"));
+ if (!(*current_selection)->get_ref()->hasAttribute(attr_name))
+ {
+ /* attributes of an element which aren't already in the tree getting added with red text color
+ */
+ auto type_name = static_cast(child->getAttribute("type"));
+ attr_type.emplace(attr_name, type_name);
+ QString tooltipString =
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), attr_name)[1].c_str();
+ tooltipString.append(". Default: ");
+ tooltipString.append(
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), attr_name)[0].c_str());
+
+ if (combo_box_attr.contains(attr_name.c_str()))
+ {
+ lineEdit = new QComboBox(this);
+ grplot_widget->advancedAttributeComboBoxHandler(
+ attr_name, (*current_selection)->get_ref()->localName(), &lineEdit);
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ }
+ else if (check_box_attr.contains(attr_name.c_str()))
+ {
+ lineEdit = new QCheckBox(this);
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ ((QCheckBox *)lineEdit)
+ ->setChecked(static_cast((*current_selection)->get_ref()->getAttribute(attr_name)) == 1);
+ }
+ else
+ {
+ lineEdit = new QLineEdit(this);
+ ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
+ ((QLineEdit *)lineEdit)->setText("");
+ }
+ QString text_label = QString("%1").arg(attr_name.c_str());
+ form->addRow(text_label, lineEdit);
+
+ labels << text_label;
+ fields << lineEdit;
+ }
+ }
+ else if (child->localName() == "xs:attributegroup")
+ {
+ /* when an element contains one or more attributegroups all attributes from these groups must be
+ * added */
+ std::shared_ptr group;
+ auto group_name = static_cast(child->getAttribute("ref"));
+
+ if (group_name != "colorrep")
+ {
+ auto attr_group_selections = schema_tree->querySelectorsAll("[name=" + group_name + "]");
+ for (const auto &selection : attr_group_selections)
+ {
+ if (selection->localName() == "xs:attributegroup") group = selection;
+ }
+
+ /* iterate through attribute elements */
+ for (const auto &childchild : group->children())
+ {
+ if (childchild->localName() == "xs:attribute")
+ {
+ auto attr_name = static_cast(childchild->getAttribute("name"));
+ if (!(*current_selection)->get_ref()->hasAttribute(attr_name))
+ {
+ /* attributes of an element which aren't already in the tree getting added with
+ * red text color */
+ auto type_name = static_cast(childchild->getAttribute("type"));
+ attr_type.emplace(attr_name, type_name);
+ QString tooltipString =
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), attr_name)[1]
+ .c_str();
+ tooltipString.append(". Default: ");
+ tooltipString.append(
+ GRM::Render::getDefaultAndTooltip((*current_selection)->get_ref(), attr_name)[0]
+ .c_str());
+
+ if (combo_box_attr.contains(attr_name.c_str()))
+ {
+ lineEdit = new QComboBox(this);
+ grplot_widget->advancedAttributeComboBoxHandler(
+ attr_name, (*current_selection)->get_ref()->localName(), &lineEdit);
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ }
+ else if (check_box_attr.contains(attr_name.c_str()))
+ {
+ lineEdit = new QCheckBox(this);
+ ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
+ ((QCheckBox *)lineEdit)
+ ->setChecked(static_cast(
+ (*current_selection)->get_ref()->getAttribute(attr_name)) == 1);
+ }
+ else
+ {
+ lineEdit = new QLineEdit(this);
+ ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
+ ((QLineEdit *)lineEdit)->setText("");
+ }
+ QString text_label =
+ QString("%1").arg(attr_name.c_str());
+ form->addRow(text_label, lineEdit);
+
+ labels << text_label;
+ fields << lineEdit;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* special case for colorrep cause there are way to many attributes inside the attributegroup
+ */
+ lineEdit = new QLineEdit(this);
+ ((QLineEdit *)lineEdit)->setText("");
+ QString text_label = QString("%1").arg("Colorrep-index");
+ form->addRow(text_label, lineEdit);
+
+ attr_type.emplace("Colorrep-index", "xs:string");
+ labels << text_label;
+ fields << lineEdit;
+
+ lineEdit = new QLineEdit(this);
+ ((QLineEdit *)lineEdit)->setText("");
+ text_label = QString("%1").arg("Colorrep-value");
+ form->addRow(text_label, lineEdit);
+
+ attr_type.emplace("Colorrep-value", "xs:string");
+ labels << text_label;
+ fields << lineEdit;
+ }
+ }
+ }
+ }
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+ QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ form->addRow(buttonBox);
+
+ auto scrollAreaContent = new QWidget;
+ scrollAreaContent->setLayout(form);
+
+ auto scrollArea = new QScrollArea;
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setWidget(scrollAreaContent);
+
+ auto groupBoxLayout = new QVBoxLayout;
+ groupBoxLayout->addWidget(scrollArea);
+ this->setLayout(groupBoxLayout);
+ this->resize(std::min(grplot_widget->width(), form->sizeHint().width() + this->layout()->sizeHint().width()),
+ std::min(grplot_widget->height(), form->sizeHint().height() + this->layout()->sizeHint().height()));
+}
+
+void EditElementWidget::reject()
+{
+ grplot_widget->setTreeUpdate(false);
+ fields.clear();
+ labels.clear();
+ attr_type.clear();
+ this->close();
+}
+
+void EditElementWidget::accept()
+{
+ auto current_selection = grplot_widget->get_current_selection();
+ for (int i = 0; i < labels.count(); i++)
+ {
+ auto &field = *fields[i]; // because typeid(*fields[i]) is bad :(
+ if (util::startsWith(labels[i].toStdString(), "") &&
+ util::endsWith(labels[i].toStdString(), ""))
+ {
+ labels[i].remove(0, 29);
+ labels[i].remove(labels[i].size() - 7, 7);
+ }
+ std::string attr_name = labels[i].toStdString();
+ if (typeid(field) == typeid(QLineEdit) && ((QLineEdit *)fields[i])->isModified())
+ {
+ std::string name = std::string((*current_selection)->get_ref()->getAttribute("name"));
+ if (((QLineEdit *)fields[i])->text().toStdString().empty() && labels[i].toStdString() != "tick_label" &&
+ labels[i].toStdString() != "text")
+ {
+ /* remove attributes from tree when the value got removed */
+ (*current_selection)->get_ref()->removeAttribute(labels[i].toStdString());
+ }
+ else
+ {
+ if (labels[i].toStdString() == "text")
+ {
+ const std::string value = ((QLineEdit *)fields[i])->text().toStdString();
+ if (attr_type[attr_name] == "xs:string" ||
+ (attr_type[attr_name] == "strint" && !util::is_digits(value)))
+ {
+ if ((*current_selection)->get_ref()->parentElement()->localName() == "text_region")
+ {
+ (*current_selection)
+ ->get_ref()
+ ->parentElement()
+ ->parentElement()
+ ->setAttribute("text_content", value);
+ }
+ else if (name == "xlabel" || name == "ylabel")
+ {
+ (*current_selection)
+ ->get_ref()
+ ->parentElement()
+ ->parentElement()
+ ->querySelectors(name)
+ ->setAttribute(name, value);
+ }
+ }
+ else if (attr_type[attr_name] == "xs:double")
+ {
+ (*current_selection)
+ ->get_ref()
+ ->parentElement()
+ ->setAttribute(labels[i].toStdString(), std::stod(value));
+ }
+ else if (attr_type[attr_name] == "xs:integer" ||
+ (attr_type[attr_name] == "strint" && util::is_digits(value)))
+ {
+ (*current_selection)
+ ->get_ref()
+ ->parentElement()
+ ->setAttribute(labels[i].toStdString(), std::stoi(value));
+ }
+ }
+ if (labels[i].toStdString() == "Colorrep-index")
+ {
+ /* special case for colorrep attribute */
+ (*current_selection)
+ ->get_ref()
+ ->setAttribute("colorrep." + ((QLineEdit *)fields[i])->text().toStdString(),
+ ((QLineEdit *)fields[i + 1])->text().toStdString());
+ }
+ else if (labels[i].toStdString() != "Colorrep-value")
+ {
+ const std::string value = ((QLineEdit *)fields[i])->text().toStdString();
+ if (attr_type[attr_name] == "xs:string" ||
+ (attr_type[attr_name] == "strint" && !util::is_digits(value)))
+ {
+ (*current_selection)->get_ref()->setAttribute(labels[i].toStdString(), value);
+ }
+ else if (attr_type[attr_name] == "xs:double")
+ {
+ (*current_selection)->get_ref()->setAttribute(labels[i].toStdString(), std::stod(value));
+ }
+ else if (attr_type[attr_name] == "xs:integer" ||
+ (attr_type[attr_name] == "strint" && util::is_digits(value)))
+ {
+ (*current_selection)->get_ref()->setAttribute(labels[i].toStdString(), std::stoi(value));
+ }
+ }
+ }
+ }
+ else if (typeid(field) == typeid(QComboBox))
+ {
+ int index = ((QComboBox *)fields[i])->currentIndex();
+ if (((QComboBox *)fields[i])->itemText(index).toStdString().empty())
+ {
+ /* remove attributes from tree when the value got removed */
+ (*current_selection)->get_ref()->removeAttribute(labels[i].toStdString());
+ }
+ else
+ {
+ const std::string value = ((QComboBox *)fields[i])->itemText(index).toStdString();
+ grplot_widget->attributeSetForComboBox(attr_type[attr_name], (*current_selection)->get_ref(), value,
+ (labels[i]).toStdString());
+ }
+ }
+ else if (typeid(field) == typeid(QCheckBox))
+ {
+ (*current_selection)->get_ref()->setAttribute(labels[i].toStdString(), ((QCheckBox *)fields[i])->isChecked());
+ }
+ }
+ grplot_widget->setTreeUpdate(true);
+ if (getenv("GRM_DEBUG"))
+ {
+ std::cerr << toXML(grm_get_document_root(),
+ GRM::SerializerOptions{std::string(2, ' '),
+ GRM::SerializerOptions::InternalAttributesFormat::Plain})
+ << "\n";
+ }
+ grplot_widget->editElementAccepted();
+ fields.clear();
+ labels.clear();
+ attr_type.clear();
+ this->close();
+}
+
+void EditElementWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) accept();
+}
diff --git a/lib/grm/grplot/gredit/EditElementWidget.h b/lib/grm/grplot/gredit/EditElementWidget.h
new file mode 100644
index 000000000..7d1343ea6
--- /dev/null
+++ b/lib/grm/grplot/gredit/EditElementWidget.h
@@ -0,0 +1,44 @@
+#ifndef EDITELEMENTWIDGET_H
+#define EDITELEMENTWIDGET_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "grm.h"
+class EditElementWidget;
+#include "../grplot_widget.hxx"
+
+
+class EditElementWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit EditElementWidget(GRPlotWidget *widget, QWidget *parent = nullptr);
+
+ void AttributeEditEvent();
+
+private slots:
+ void reject();
+ void accept();
+
+protected:
+ void keyPressEvent(QKeyEvent *event) override;
+
+private:
+ GRPlotWidget *grplot_widget;
+ std::shared_ptr schema_tree;
+ QList labels;
+ QList fields;
+ std::unordered_map attr_type;
+};
+
+
+#endif // EDITELEMENTWIDGET_H
diff --git a/lib/grm/grplot/gredit/TableWidget.cpp b/lib/grm/grplot/gredit/TableWidget.cpp
new file mode 100644
index 000000000..a76532a9b
--- /dev/null
+++ b/lib/grm/grplot/gredit/TableWidget.cpp
@@ -0,0 +1,247 @@
+#include "TableWidget.h"
+
+#include
+#include
+#include
+
+
+TableWidget::TableWidget(GRPlotWidget *widget, QWidget *parent) : QTableWidget(parent)
+{
+ grplot_widget = widget;
+ this->setWindowTitle("DOM-Tree Data-Context Viewer");
+ this->setRowCount(2);
+ this->setVerticalHeaderItem(0, new QTableWidgetItem("Context-Key"));
+}
+
+std::map>
+TableWidget::extractContextNames(const std::shared_ptr context)
+{
+ int col_cnt = 0;
+ std::map> context_data;
+ std::vector cntxt_names;
+
+ context_data = grm_get_context_data();
+
+ for (const auto &entry : context_data)
+ {
+ col_cnt += 1;
+ cntxt_names.push_back(entry.first);
+ }
+ this->col_num = col_cnt;
+ this->context_names = cntxt_names;
+ return context_data;
+}
+
+void TableWidget::updateData(const std::shared_ptr context)
+{
+ int max_rows = 0, col = 0;
+ std::map> context_data;
+
+ // disconnect so that a reread wont trigger applyTableChanges
+ disconnect(this, SIGNAL(cellChanged(int, int)), this, SLOT(applyTableChanges(int, int)));
+ this->context = context;
+ this->context_attributes = getContextAttributes();
+
+ context_data = extractContextNames(context);
+ this->setColumnCount(this->col_num);
+
+ for (const auto &entry : context_data)
+ {
+ int row = 1;
+ this->setItem(0, col, new QTableWidgetItem(entry.first.c_str()));
+ max_rows = std::max(max_rows, (int)entry.second.size() + 1);
+ this->setRowCount(max_rows);
+ for (const auto &str : entry.second)
+ {
+ this->setItem(row, col, new QTableWidgetItem(str.c_str()));
+ row += 1;
+ }
+ col += 1;
+ }
+
+ for (int i = 1; i <= max_rows; i++)
+ {
+ this->setVerticalHeaderItem(i, new QTableWidgetItem(std::to_string(i).c_str()));
+ }
+
+ connect(this, SIGNAL(cellChanged(int, int)), this, SLOT(applyTableChanges(int, int)));
+ connect(this, SIGNAL(cellClicked(int, int)), this, SLOT(showUsagesOfContext(int, int)));
+}
+
+void TableWidget::applyTableChanges(int row, int column)
+{
+ std::string new_value = this->item(row, column)->text().toStdString();
+
+ if (getenv("GRM_DEBUG"))
+ fprintf(stderr, "Detected change at (%i/%i) with value '%s'. Old value was '%s'\n", row, column, new_value.c_str(),
+ this->context_names[column].c_str());
+
+ if (row != 0)
+ {
+ // data has been changed -> apply these changes to the context
+ auto context_key = this->item(0, column)->text().toStdString();
+
+ if ((*this->context)[context_key].doubleUsed())
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ if (vec.size() > row)
+ {
+ vec[row - 1] = atof(new_value.c_str());
+ (*this->context)[context_key] = vec;
+ }
+ else
+ {
+ // only allow to edit non empty lines to prevent multiple complications with size mismatches
+ this->item(row, column)->setText("");
+ }
+ }
+ else if ((*this->context)[context_key].intUsed())
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ if (vec.size() > row)
+ {
+ vec[row - 1] = atoi(new_value.c_str());
+ (*this->context)[context_key] = vec;
+ }
+ else
+ {
+ // only allow to edit non empty lines to prevent multiple complications with size mismatches
+ this->item(row, column)->setText("");
+ }
+ }
+ else
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ if (vec.size() > row)
+ {
+ vec[row - 1] = new_value;
+ (*this->context)[context_key] = vec;
+ }
+ else
+ {
+ // only allow to edit non empty lines to prevent multiple complications with size mismatches
+ this->item(row, column)->setText("");
+ }
+ }
+ this->grplot_widget->redraw();
+ }
+ else
+ {
+ // the name of the context got changed -> replace the key inside the context and update tree attributes
+ auto context_key = this->context_names[column].c_str();
+
+ if ((*this->context)[context_key].doubleUsed())
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ (*this->context)[new_value] = vec;
+ }
+ else if ((*this->context)[context_key].intUsed())
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ (*this->context)[new_value] = vec;
+ }
+ else
+ {
+ auto vec = GRM::get>((*this->context)[context_key]);
+ (*this->context)[new_value] = vec;
+ }
+ addValidContextKey(new_value); // add the name to valid keys so it could also be exported and updated
+
+ // get the plain XML-tree and use the string find option to get attr=value -> use this information to select the
+ // tree element and update the value with the new context name
+ // all that is needed cause u can't search just for the value with the selector
+ auto tree_str = GRM::toXML(
+ grm_get_document_root(),
+ GRM::SerializerOptions{std::string(2, ' '), GRM::SerializerOptions::InternalAttributesFormat::Plain});
+ std::string token = "=\"" + std::string(context_key) + "\"";
+ while (tree_str.find(token) != std::string::npos)
+ {
+ int max_attr_length = 50;
+ auto pos = tree_str.find(token);
+ auto interesting_part =
+ tree_str.substr(std::max(0, pos - max_attr_length), max_attr_length + token.size());
+ auto start = interesting_part.find_last_of(" ");
+ auto selector_token = interesting_part.substr(start + 1, (max_attr_length - start - 1) + token.size());
+ auto attr = interesting_part.substr(start + 1, (max_attr_length - start - 1));
+ tree_str = tree_str.substr(pos + token.size(), std::string::npos);
+
+ if (getenv("GRM_DEBUG"))
+ fprintf(stderr, "Replace the value of %s with the new user-defined name\n", selector_token.c_str());
+
+ if (std::find(this->context_attributes.begin(), this->context_attributes.end(), attr) ==
+ this->context_attributes.end())
+ continue;
+ for (const auto &elem : grm_get_document_root()->querySelectorsAll("[" + selector_token + "]"))
+ {
+ if (static_cast(elem->getAttribute(attr)) == std::string(context_key))
+ {
+ elem->setAttribute(attr, new_value);
+ (*this->context)[context_key].decrement_key(context_key);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void TableWidget::showUsagesOfContext(int row, int column)
+{
+ referenced_attributes.clear();
+ if (row == 0)
+ {
+ auto context_ref_name = this->item(row, column)->text().toStdString();
+
+ // get the plain XML-tree and use the string find option to get attr=value -> use this information to select the
+ // tree element and update the value with the new context name
+ // all that is needed cause u can't search just for the value with the selector
+ auto tree_str = GRM::toXML(
+ grm_get_document_root(),
+ GRM::SerializerOptions{std::string(2, ' '), GRM::SerializerOptions::InternalAttributesFormat::Plain});
+ std::string token = "=\"" + std::string(context_ref_name) + "\"";
+ while (tree_str.find(token) != std::string::npos)
+ {
+ int max_attr_length = 50;
+ auto pos = tree_str.find(token);
+ auto interesting_part =
+ tree_str.substr(std::max(0, pos - max_attr_length), max_attr_length + token.size());
+ auto start = interesting_part.find_last_of(" ");
+ auto selector_token = interesting_part.substr(start + 1, (max_attr_length - start - 1) + token.size());
+ auto attr = interesting_part.substr(start + 1, (max_attr_length - start - 1));
+ tree_str = tree_str.substr(pos + token.size(), std::string::npos);
+
+ if (std::find(this->context_attributes.begin(), this->context_attributes.end(), attr) ==
+ this->context_attributes.end())
+ continue;
+ for (const auto &elem : grm_get_document_root()->querySelectorsAll("[" + selector_token + "]"))
+ {
+ bool skip = false;
+ if (static_cast(elem->getAttribute(attr)) == std::string(context_ref_name))
+ {
+ auto bbox_id = static_cast(elem->getAttribute("_bbox_id"));
+ auto bbox_x_min = static_cast(elem->getAttribute("_bbox_x_min"));
+ auto bbox_x_max = static_cast(elem->getAttribute("_bbox_x_max"));
+ auto bbox_y_min = static_cast(elem->getAttribute("_bbox_y_min"));
+ auto bbox_y_max = static_cast(elem->getAttribute("_bbox_y_max"));
+ const Bounding_object bbox =
+ Bounding_object(bbox_id, bbox_x_min, bbox_x_max, bbox_y_min, bbox_y_max, elem);
+ for (const auto &vec_elem : referenced_attributes)
+ {
+ if (vec_elem.get_ref() == elem)
+ {
+ skip = true;
+ break;
+ }
+ }
+ if (!skip) referenced_attributes.emplace_back(bbox);
+ }
+ }
+ }
+ }
+ this->grplot_widget->set_referenced_elements(this->referenced_attributes);
+ this->grplot_widget->redraw();
+}
+
+std::vector TableWidget::getContextNames()
+{
+ return this->context_names;
+}
diff --git a/lib/grm/grplot/gredit/TableWidget.h b/lib/grm/grplot/gredit/TableWidget.h
new file mode 100644
index 000000000..adeb88167
--- /dev/null
+++ b/lib/grm/grplot/gredit/TableWidget.h
@@ -0,0 +1,33 @@
+#ifndef TABLEWIDGET_H
+#define TABLEWIDGET_H
+
+#include
+#include
+
+class TableWidget;
+#include "../grplot_widget.hxx"
+
+class TableWidget : public QTableWidget
+{
+ Q_OBJECT
+public:
+ explicit TableWidget(GRPlotWidget *widget, QWidget *parent = nullptr);
+ std::map> extractContextNames(const std::shared_ptr context);
+ void updateData(std::shared_ptr context);
+ std::vector getContextNames();
+
+private slots:
+ void applyTableChanges(int row, int column);
+ void showUsagesOfContext(int row, int column);
+
+private:
+ GRPlotWidget *grplot_widget;
+ std::shared_ptr context;
+ std::vector context_names;
+ std::vector context_attributes;
+ std::vector referenced_attributes;
+ int col_num;
+};
+
+
+#endif // TABLEWIDGET_H
diff --git a/lib/grm/grplot/grplot.cxx b/lib/grm/grplot/grplot.cxx
index 0620db609..ec8003199 100644
--- a/lib/grm/grplot/grplot.cxx
+++ b/lib/grm/grplot/grplot.cxx
@@ -30,7 +30,7 @@ int main(int argc, char **argv)
#else
std::cerr << e.what() << std::endl;
#endif
- std::cerr << "Failed to set the \"GRDIR\" envionment variable, falling back to GRDIR=\"" << GRDIR << "\"."
+ std::cerr << "Failed to set the \"GRDIR\" environment variable, falling back to GRDIR=\"" << GRDIR << "\"."
<< std::endl;
}
diff --git a/lib/grm/grplot/grplot.pro b/lib/grm/grplot/grplot.pro
index c3723aabd..c62d0fb17 100644
--- a/lib/grm/grplot/grplot.pro
+++ b/lib/grm/grplot/grplot.pro
@@ -11,8 +11,8 @@ DEFINES += GRDIR=\\\"$(GRDIR)\\\"
QMAKE_CXXFLAGS += -std=c++17 $$(XERCESCDEFS) $$(EXTRA_CXXFLAGS)
QMAKE_LFLAGS += $$(EXTRA_LDFLAGS)
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.15
-HEADERS += grplot_widget.hxx grplot_mainwindow.hxx util.hxx gredit/Bounding_logic.h gredit/Bounding_object.h gredit/CustomTreeWidgetItem.h gredit/TreeWidget.h gredit/AddElementWidget.h qtterm/grm_args_t_wrapper.h qtterm/receiver_thread.h
-SOURCES += grplot_widget.cxx grplot.cxx grplot_mainwindow.cxx util.cxx gredit/Bounding_logic.cpp gredit/Bounding_object.cpp gredit/CustomTreeWidgetItem.cpp gredit/TreeWidget.cpp gredit/AddElementWidget.cpp qtterm/grm_args_t_wrapper.cpp qtterm/receiver_thread.cpp
+HEADERS += grplot_widget.hxx grplot_mainwindow.hxx util.hxx gredit/Bounding_logic.h gredit/Bounding_object.h gredit/CustomTreeWidgetItem.h gredit/TreeWidget.h gredit/AddElementWidget.h gredit/TableWidget.h gredit/EditElementWidget.h qtterm/grm_args_t_wrapper.h qtterm/receiver_thread.h
+SOURCES += grplot_widget.cxx grplot.cxx grplot_mainwindow.cxx util.cxx gredit/Bounding_logic.cpp gredit/Bounding_object.cpp gredit/CustomTreeWidgetItem.cpp gredit/TreeWidget.cpp gredit/AddElementWidget.cpp gredit/TableWidget.cpp gredit/EditElementWidget.cpp qtterm/grm_args_t_wrapper.cpp qtterm/receiver_thread.cpp
INCLUDEPATH += ../include ../../gr
if (macx) {
if (exists(../libGRM.dylib)) {
diff --git a/lib/grm/grplot/grplot_widget.cxx b/lib/grm/grplot/grplot_widget.cxx
index 6afa34dfd..815eaa5db 100644
--- a/lib/grm/grplot/grplot_widget.cxx
+++ b/lib/grm/grplot/grplot_widget.cxx
@@ -1,7 +1,4 @@
#include
-#include
-#include
-#include
#include
#include
#include
@@ -13,20 +10,14 @@
#include
#include
-#include
-#include
-#include
-#include
#include
#include
#include
#include
#include
#include
-#include
#include
#include
-#include
#include
#include
#include
@@ -101,6 +92,10 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
amount_scrolled = 0;
treewidget = new TreeWidget(this);
treewidget->hide();
+ table_widget = new TableWidget(this);
+ table_widget->hide();
+ edit_element_widget = new EditElementWidget(this);
+ edit_element_widget->hide();
selected_parent = nullptr;
csr = new QCursor(Qt::ArrowCursor);
setCursor(*csr);
@@ -108,7 +103,9 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
combo_box_attr = QStringList{
"algorithm",
"axis_type",
+ "clip_region",
"colormap",
+ "error_bar_style",
"font",
"font_precision",
"kind",
@@ -142,6 +139,7 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
"adjust_x_lim",
"adjust_y_lim",
"adjust_z_lim",
+ "clip_negative",
"disable_x_trans",
"disable_y_trans",
"draw_grid",
@@ -150,12 +148,14 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
"is_major",
"is_mirrored",
"keep_aspect_ratio",
+ "keep_radii_axes",
"keep_window",
"marginal_heatmap_side_plot",
"mirrored_axis",
"movable",
"only_quadratic_aspect_ratio",
"phi_flip",
+ "polar_with_pan",
"set_text_color_for_background",
"space",
"stairs",
@@ -172,6 +172,13 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
"z_log",
};
+ // add context attributes to combobox list
+ auto context_attributes = getContextAttributes();
+ for (const auto &attr : context_attributes)
+ {
+ combo_box_attr.push_back(attr.c_str());
+ }
+
#ifdef _WIN32
putenv("GKS_WSTYPE=381");
putenv("GKS_DOUBLE_BUF=True");
@@ -354,7 +361,7 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
connect(histAct, &QAction::triggered, this, &GRPlotWidget::hist);
barplotAct = new QAction(tr("&Barplot"), this);
connect(barplotAct, &QAction::triggered, this, &GRPlotWidget::barplot);
- stairsAct = new QAction(tr("&Step"), this);
+ stairsAct = new QAction(tr("&Stairs"), this);
connect(stairsAct, &QAction::triggered, this, &GRPlotWidget::stairs);
stemAct = new QAction(tr("&Stem"), this);
connect(stemAct, &QAction::triggered, this, &GRPlotWidget::stem);
@@ -372,6 +379,15 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
type->addAction(shadeAct);
type->addAction(hexbinAct);
}
+ else if (strcmp(kind, "polar_line") == 0 || strcmp(kind, "polar_scatter") == 0)
+ {
+ polarLineAct = new QAction(tr("&Polar Line"), this);
+ connect(polarLineAct, &QAction::triggered, this, &GRPlotWidget::polar_line);
+ polarScatterAct = new QAction(tr("&Polar Scatter"), this);
+ connect(polarScatterAct, &QAction::triggered, this, &GRPlotWidget::polar_scatter);
+ type->addAction(polarLineAct);
+ type->addAction(polarScatterAct);
+ }
moveableModeAct = new QAction(tr("&Disable movable transformation"), this);
connect(moveableModeAct, &QAction::triggered, this, &GRPlotWidget::moveableMode);
modi_menu->addAction(moveableModeAct);
@@ -434,7 +450,28 @@ GRPlotWidget::GRPlotWidget(QMainWindow *parent, int argc, char **argv)
QObject::connect(add_element_action, SIGNAL(triggered()), this, SLOT(add_element_slot()));
add_element_action->setVisible(false);
- if (strcmp(argv[1], "--test") != 0 && !test_commands_stream) menu->addMenu(editor_menu);
+ context_menu = new QMenu("&Data");
+ add_context_data = new QMenu("Add Data-Context");
+ show_context_action = new QAction(tr("&Display Data-Context"));
+ show_context_action->setCheckable(true);
+ QObject::connect(show_context_action, SIGNAL(triggered()), this, SLOT(showContextSlot()));
+ context_menu->addAction(show_context_action);
+ add_context_action = new QAction(tr("&Column files"));
+ QObject::connect(add_context_action, SIGNAL(triggered()), this, SLOT(addContextSlot()));
+ add_context_data->addAction(add_context_action);
+ add_grplot_data_context = new QAction(tr("&Interpret matrix as 1 column data"));
+ QObject::connect(add_grplot_data_context, SIGNAL(triggered()), this, SLOT(addGRPlotDataContextSlot()));
+ add_context_data->addAction(add_grplot_data_context);
+ generate_linear_context_action = new QAction(tr("&Generate linear Data-Context"));
+ QObject::connect(generate_linear_context_action, SIGNAL(triggered()), this, SLOT(generateLinearContextSlot()));
+ add_context_data->addAction(generate_linear_context_action);
+
+ if (strcmp(argv[1], "--test") != 0 && !test_commands_stream)
+ {
+ menu->addMenu(editor_menu);
+ menu->addMenu(context_menu);
+ context_menu->addMenu(add_context_data);
+ }
}
global_root = grm_get_document_root();
}
@@ -457,7 +494,8 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
QWidget **lineEdit)
{
QStringList size_unit_list, colormap_list, font_list, font_precision_list, line_type_list, location_list,
- marker_type_list, text_align_horizontal_list, text_align_vertical_list, algorithm_volume_list, model_list;
+ marker_type_list, text_align_horizontal_list, text_align_vertical_list, algorithm_volume_list, model_list,
+ context_attr_list;
auto size_unit_vec = getSizeUnits();
size_unit_list.reserve((int)size_unit_vec.size());
for (auto &i : size_unit_vec)
@@ -524,11 +562,22 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
{
model_list.push_back(i.c_str());
}
+ table_widget->extractContextNames(grm_get_render()->getContext());
+ auto context_attr_vec = table_widget->getContextNames();
+ context_attr_list.reserve((int)context_attr_vec.size());
+ for (auto &i : context_attr_vec)
+ {
+ context_attr_list.push_back(i.c_str());
+ }
QStringList axis_type_list{
"x",
"y",
};
+ QStringList clip_region_list{
+ "quadratic",
+ "elliptic",
+ };
QStringList orientation_list{
"vertical",
"horizontal",
@@ -537,6 +586,10 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
"sum",
"max",
};
+ QStringList error_bar_style_list{
+ "line",
+ "area",
+ };
QStringList marginal_heatmap_kind_list{
"all",
"line",
@@ -591,6 +644,8 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
QStringList side_region_location_list{"top", "right", "bottom", "left"};
static std::map attributeToList{
{"axis_type", axis_type_list},
+ {"error_bar_style", error_bar_style_list},
+ {"clip_region", clip_region_list},
{"size_x_unit", size_unit_list},
{"size_y_unit", size_unit_list},
{"colormap", colormap_list},
@@ -618,6 +673,14 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
{"z_org_pos", org_pos_list},
{"tick_orientation", tick_orientation_list},
};
+ // add for all context attributes all possible values
+ for (const auto &attr : getContextAttributes())
+ {
+ if (attributeToList.count(attr) >= 1)
+ attributeToList[attr] = context_attr_list;
+ else
+ attributeToList.emplace(attr, context_attr_list);
+ }
((QComboBox *)*lineEdit)->setEditable(true);
if (attributeToList.count(cur_attr_name))
@@ -661,7 +724,7 @@ void GRPlotWidget::attributeComboBoxHandler(const std::string &cur_attr_name, st
QStringList plot3_group = {"plot3", "scatter", "scatter3", "tricontour", "trisurface"};
QStringList barplot_group = {"barplot", "hist", "stem", "stairs"};
QStringList hexbin_group = {"hexbin", "shade"};
- QStringList other_kinds = {"pie", "polar_histogram", "polar", "polar_heatmap", "polar_histogram", "quiver"};
+ QStringList other_kinds = {"pie", "polar_heatmap", "polar_histogram", "polar_line", "polar_scatter", "quiver"};
std::string kind;
if (util::startsWith(cur_elem_name, "series_")) kind = cur_elem_name.erase(0, 7);
@@ -771,6 +834,10 @@ void GRPlotWidget::advancedAttributeComboBoxHandler(const std::string &cur_attr_
{
current_text = locationIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
}
+ else if (cur_attr_name == "clip_region" && current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
+ {
+ current_text = clipRegionIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
+ }
else if (cur_attr_name == "colormap" && current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
{
current_text = colormapIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
@@ -797,6 +864,11 @@ void GRPlotWidget::advancedAttributeComboBoxHandler(const std::string &cur_attr_
{
current_text = lineTypeIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
}
+ else if (cur_attr_name == "resample_method" && current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
+ {
+ current_text =
+ resampleMethodIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
+ }
else if (cur_attr_name == "scientific_format" && current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
{
current_text =
@@ -807,6 +879,11 @@ void GRPlotWidget::advancedAttributeComboBoxHandler(const std::string &cur_attr_
current_text =
tickOrientationIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
}
+ else if (cur_attr_name == "error_bar_style" && current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
+ {
+ current_text =
+ errorBarStyleIntToString(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)));
+ }
int index = ((QComboBox *)*lineEdit)->findText(current_text.c_str());
if (index == -1) index += ((QComboBox *)*lineEdit)->count();
((QComboBox *)*lineEdit)->setCurrentIndex(index);
@@ -845,6 +922,10 @@ void GRPlotWidget::attributeSetForComboBox(const std::string &attr_type, std::sh
{
element->setAttribute(label, locationStringToInt(value));
}
+ else if (label == "clip_region")
+ {
+ element->setAttribute(label, clipRegionStringToInt(value));
+ }
else if (label == "colormap")
{
element->setAttribute(label, colormapStringToInt(value));
@@ -869,6 +950,10 @@ void GRPlotWidget::attributeSetForComboBox(const std::string &attr_type, std::sh
{
element->setAttribute(label, lineTypeStringToInt(value));
}
+ else if (label == "resample_method")
+ {
+ element->setAttribute(label, resampleMethodStringToInt(value));
+ }
else if (label == "tick_orientation")
{
element->setAttribute(label, tickOrientationStringToInt(value));
@@ -877,6 +962,10 @@ void GRPlotWidget::attributeSetForComboBox(const std::string &attr_type, std::sh
{
element->setAttribute(label, scientificFormatStringToInt(value));
}
+ else if (label == "error_bar_style")
+ {
+ element->setAttribute(label, errorBarStyleStringToInt(value));
+ }
else
{
element->setAttribute(label, std::stoi(value));
@@ -886,370 +975,8 @@ void GRPlotWidget::attributeSetForComboBox(const std::string &attr_type, std::sh
void GRPlotWidget::AttributeEditEvent()
{
- if (current_selection == nullptr)
- {
- return;
- }
- std::string currently_clicked_name = current_selection->get_ref()->localName();
-
- QDialog dialog(this);
- QString title("Selected: ");
- title.append(currently_clicked_name.c_str());
- dialog.setWindowTitle(title);
- auto changeParametersLabel = new QLabel("Change Parameters:");
- changeParametersLabel->setStyleSheet("font-weight: bold");
- auto form = new QFormLayout;
- form->addRow(changeParametersLabel);
-
- QList labels;
- QList fields;
- QWidget *lineEdit;
- std::unordered_map attr_type;
-
- for (const auto &cur_attr_name : current_selection->get_ref()->getAttributeNames())
- {
- if (util::startsWith(cur_attr_name, "_"))
- {
- continue;
- }
- QString tooltipString = GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), cur_attr_name)[1].c_str();
- tooltipString.append(". Default: ");
- tooltipString.append(GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), cur_attr_name)[0].c_str());
-
- if (combo_box_attr.contains(cur_attr_name.c_str()))
- {
- lineEdit = new QComboBox(&dialog);
- advancedAttributeComboBoxHandler(cur_attr_name, current_selection->get_ref()->localName(), &lineEdit);
- if (current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
- {
- attr_type.emplace(cur_attr_name, "xs:integer");
- }
- else if (current_selection->get_ref()->getAttribute(cur_attr_name).isDouble())
- {
- attr_type.emplace(cur_attr_name, "xs:double");
- }
- else
- {
- attr_type.emplace(cur_attr_name, "xs:string");
- }
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- }
- else if (check_box_attr.contains(cur_attr_name.c_str()))
- {
- lineEdit = new QCheckBox(&dialog);
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- ((QCheckBox *)lineEdit)
- ->setChecked(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)) == 1);
- }
- else
- {
- if (current_selection->get_ref()->getAttribute(cur_attr_name).isInt())
- {
- attr_type.emplace(cur_attr_name, "xs:integer");
- }
- else if (current_selection->get_ref()->getAttribute(cur_attr_name).isDouble())
- {
- attr_type.emplace(cur_attr_name, "xs:double");
- }
- else
- {
- attr_type.emplace(cur_attr_name, "xs:string");
- }
- lineEdit = new QLineEdit(&dialog);
- ((QLineEdit *)lineEdit)
- ->setText(static_cast(current_selection->get_ref()->getAttribute(cur_attr_name)).c_str());
- ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
- }
- QString text_label = QString(cur_attr_name.c_str());
- form->addRow(text_label, lineEdit);
-
- labels << text_label;
- fields << lineEdit;
- }
-
- if (schema_tree != nullptr)
- {
- std::shared_ptr element;
- auto selections = schema_tree->querySelectorsAll("[name=" + currently_clicked_name + "]");
- for (const auto &selection : selections)
- {
- if (selection->localName() == "xs:element") element = selection->children()[0];
- }
-
- /* iterate through complextype elements */
- for (const auto &child : element->children())
- {
- if (child->localName() == "xs:attribute")
- {
- auto attr_name = static_cast(child->getAttribute("name"));
- if (!current_selection->get_ref()->hasAttribute(attr_name))
- {
- /* attributes of an element which aren't already in the tree getting added with red text color
- */
- auto type_name = static_cast(child->getAttribute("type"));
- attr_type.emplace(attr_name, type_name);
- QString tooltipString =
- GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), attr_name)[1].c_str();
- tooltipString.append(". Default: ");
- tooltipString.append(
- GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), attr_name)[0].c_str());
-
- if (combo_box_attr.contains(attr_name.c_str()))
- {
- lineEdit = new QComboBox(&dialog);
- advancedAttributeComboBoxHandler(attr_name, current_selection->get_ref()->localName(), &lineEdit);
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- }
- else if (check_box_attr.contains(attr_name.c_str()))
- {
- lineEdit = new QCheckBox(&dialog);
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- ((QCheckBox *)lineEdit)
- ->setChecked(static_cast(current_selection->get_ref()->getAttribute(attr_name)) == 1);
- }
- else
- {
- lineEdit = new QLineEdit(&dialog);
- ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
- ((QLineEdit *)lineEdit)->setText("");
- }
- QString text_label = QString("%1").arg(attr_name.c_str());
- form->addRow(text_label, lineEdit);
-
- labels << text_label;
- fields << lineEdit;
- }
- }
- else if (child->localName() == "xs:attributegroup")
- {
- /* when an element contains one or more attributegroups all attributes from these groups must be
- * added */
- std::shared_ptr group;
- auto group_name = static_cast(child->getAttribute("ref"));
-
- if (group_name != "colorrep")
- {
- auto attr_group_selections = schema_tree->querySelectorsAll("[name=" + group_name + "]");
- for (const auto &selection : attr_group_selections)
- {
- if (selection->localName() == "xs:attributegroup") group = selection;
- }
-
- /* iterate through attribute elements */
- for (const auto &childchild : group->children())
- {
- if (childchild->localName() == "xs:attribute")
- {
- auto attr_name = static_cast(childchild->getAttribute("name"));
- if (!current_selection->get_ref()->hasAttribute(attr_name))
- {
- /* attributes of an element which aren't already in the tree getting added with
- * red text color */
- auto type_name = static_cast(childchild->getAttribute("type"));
- attr_type.emplace(attr_name, type_name);
- QString tooltipString =
- GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), attr_name)[1].c_str();
- tooltipString.append(". Default: ");
- tooltipString.append(
- GRM::Render::getDefaultAndTooltip(current_selection->get_ref(), attr_name)[0]
- .c_str());
-
- if (combo_box_attr.contains(attr_name.c_str()))
- {
- lineEdit = new QComboBox(&dialog);
- advancedAttributeComboBoxHandler(attr_name, current_selection->get_ref()->localName(),
- &lineEdit);
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- }
- else if (check_box_attr.contains(attr_name.c_str()))
- {
- lineEdit = new QCheckBox(&dialog);
- ((QCheckBox *)lineEdit)->setToolTip(tooltipString);
- ((QCheckBox *)lineEdit)
- ->setChecked(
- static_cast(current_selection->get_ref()->getAttribute(attr_name)) == 1);
- }
- else
- {
- lineEdit = new QLineEdit(&dialog);
- ((QLineEdit *)lineEdit)->setToolTip(tooltipString);
- ((QLineEdit *)lineEdit)->setText("");
- }
- QString text_label =
- QString("%1").arg(attr_name.c_str());
- form->addRow(text_label, lineEdit);
-
- labels << text_label;
- fields << lineEdit;
- }
- }
- }
- }
- else
- {
- /* special case for colorrep cause there are way to many attributes inside the attributegroup
- */
- lineEdit = new QLineEdit(&dialog);
- ((QLineEdit *)lineEdit)->setText("");
- QString text_label = QString("%1").arg("Colorrep-index");
- form->addRow(text_label, lineEdit);
-
- attr_type.emplace("Colorrep-index", "xs:string");
- labels << text_label;
- fields << lineEdit;
-
- lineEdit = new QLineEdit(&dialog);
- ((QLineEdit *)lineEdit)->setText("");
- text_label = QString("%1").arg("Colorrep-value");
- form->addRow(text_label, lineEdit);
-
- attr_type.emplace("Colorrep-value", "xs:string");
- labels << text_label;
- fields << lineEdit;
- }
- }
- }
- }
-
- QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
- form->addRow(&buttonBox);
- QObject::connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
- QObject::connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
-
- auto scrollAreaContent = new QWidget;
- scrollAreaContent->setLayout(form);
- auto scrollArea = new QScrollArea;
- scrollArea = new QScrollArea;
- scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- scrollArea->setWidgetResizable(true);
- scrollArea->setWidget(scrollAreaContent);
-
- auto groupBoxLayout = new QVBoxLayout;
- groupBoxLayout->addWidget(scrollArea);
- dialog.setLayout(groupBoxLayout);
-
- if (dialog.exec() == QDialog::Accepted)
- {
- for (int i = 0; i < labels.count(); i++)
- {
- qDebug() << typeid(fields[i]).name();
- auto &field = *fields[i]; // because typeid(*fields[i]) is bad :(
- if (util::startsWith(labels[i].toStdString(), "") &&
- util::endsWith(labels[i].toStdString(), ""))
- {
- labels[i].remove(0, 29);
- labels[i].remove(labels[i].size() - 7, 7);
- }
- std::string attr_name = labels[i].toStdString();
- if (typeid(field) == typeid(QLineEdit) && ((QLineEdit *)fields[i])->isModified())
- {
- std::string name = std::string(current_selection->get_ref()->getAttribute("name"));
- if (((QLineEdit *)fields[i])->text().toStdString().empty())
- {
- /* remove attributes from tree when the value got removed */
- current_selection->get_ref()->removeAttribute(labels[i].toStdString());
- }
- else
- {
- if (labels[i].toStdString() == "text")
- {
- const std::string value = ((QLineEdit *)fields[i])->text().toStdString();
- if (attr_type[attr_name] == "xs:string" ||
- (attr_type[attr_name] == "strint" && !util::is_digits(value)))
- {
- if (current_selection->get_ref()->parentElement()->localName() == "text_region")
- {
- current_selection->get_ref()->parentElement()->parentElement()->setAttribute(
- "text_content", value);
- }
- else if (name == "xlabel" || name == "ylabel")
- {
- current_selection->get_ref()
- ->parentElement()
- ->parentElement()
- ->querySelectors(name)
- ->setAttribute(name, value);
- }
- }
- else if (attr_type[attr_name] == "xs:double")
- {
- current_selection->get_ref()->parentElement()->setAttribute(labels[i].toStdString(),
- std::stod(value));
- }
- else if (attr_type[attr_name] == "xs:integer" ||
- (attr_type[attr_name] == "strint" && util::is_digits(value)))
- {
- current_selection->get_ref()->parentElement()->setAttribute(labels[i].toStdString(),
- std::stoi(value));
- }
- }
- if (labels[i].toStdString() == "Colorrep-index")
- {
- /* special case for colorrep attribute */
- current_selection->get_ref()->setAttribute("colorrep." +
- ((QLineEdit *)fields[i])->text().toStdString(),
- ((QLineEdit *)fields[i + 1])->text().toStdString());
- }
- else if (labels[i].toStdString() != "Colorrep-value")
- {
- const std::string value = ((QLineEdit *)fields[i])->text().toStdString();
- if (attr_type[attr_name] == "xs:string" ||
- (attr_type[attr_name] == "strint" && !util::is_digits(value)))
- {
- current_selection->get_ref()->setAttribute(labels[i].toStdString(), value);
- }
- else if (attr_type[attr_name] == "xs:double")
- {
- current_selection->get_ref()->setAttribute(labels[i].toStdString(), std::stod(value));
- }
- else if (attr_type[attr_name] == "xs:integer" ||
- (attr_type[attr_name] == "strint" && util::is_digits(value)))
- {
- current_selection->get_ref()->setAttribute(labels[i].toStdString(), std::stoi(value));
- }
- }
- }
- }
- else if (typeid(field) == typeid(QComboBox))
- {
- int index = ((QComboBox *)fields[i])->currentIndex();
- if (((QComboBox *)fields[i])->itemText(index).toStdString().empty())
- {
- /* remove attributes from tree when the value got removed */
- current_selection->get_ref()->removeAttribute(labels[i].toStdString());
- }
- else
- {
- const std::string value = ((QComboBox *)fields[i])->itemText(index).toStdString();
- attributeSetForComboBox(attr_type[attr_name], current_selection->get_ref(), value,
- (labels[i]).toStdString());
- }
- }
- else if (typeid(field) == typeid(QCheckBox))
- {
- current_selection->get_ref()->setAttribute(labels[i].toStdString(),
- ((QCheckBox *)fields[i])->isChecked());
- }
- }
- current_selection = nullptr;
- mouse_move_selection = nullptr;
- amount_scrolled = 0;
- tree_update = true;
- clicked.clear();
- if (getenv("GRM_DEBUG"))
- {
- std::cerr << toXML(grm_get_document_root(),
- GRM::SerializerOptions{std::string(2, ' '),
- GRM::SerializerOptions::InternalAttributesFormat::Plain})
- << "\n";
- }
- reset_pixmap();
- }
- else
- {
- tree_update = false;
- }
+ edit_element_widget->show();
+ edit_element_widget->AttributeEditEvent();
}
void GRPlotWidget::draw()
@@ -1261,7 +988,7 @@ void GRPlotWidget::draw()
if (global_root == nullptr) global_root = grm_get_document_root();
auto plot_elem = global_root->querySelectors("plot");
- auto kind = static_cast(plot_elem->getAttribute("kind"));
+ auto kind = static_cast(plot_elem->getAttribute("_kind"));
snprintf(file, 50, "grplot_%s.%s", kind.c_str(), file_export.c_str());
grm_export(file);
}
@@ -1351,6 +1078,12 @@ static const std::string accumulatedTooltipTemplate{"\
void GRPlotWidget::paintEvent(QPaintEvent *event)
{
+ if (getenv("GRDISPLAY") && strcmp(getenv("GRDISPLAY"), "edit") == 0)
+ {
+ if (!table_widget->isVisible() && show_context_action->isChecked()) show_context_action->setChecked(false);
+ if (!treewidget->isVisible() && show_container_action->isChecked()) show_container_action->setChecked(false);
+ if (!add_element_widget->isVisible() && add_element_action->isChecked()) add_element_action->setChecked(false);
+ }
util::unused(event);
paint(this);
}
@@ -1457,7 +1190,7 @@ void GRPlotWidget::paint(QPaintDevice *paint_device)
label.setHtml(QString::fromStdString(info));
if (global_root == nullptr) global_root = grm_get_document_root();
auto plot_elem = global_root->querySelectors("plot");
- kind = static_cast(plot_elem->getAttribute("kind"));
+ kind = static_cast(plot_elem->getAttribute("_kind"));
if (kind == "heatmap" || kind == "marginal_heatmap")
{
background.setAlpha(224);
@@ -1716,7 +1449,7 @@ void GRPlotWidget::mouseMoveEvent(QMouseEvent *event)
auto plot_elem = global_root->querySelectors("plot");
if (plot_elem)
{
- kind = static_cast(plot_elem->getAttribute("kind"));
+ kind = static_cast(plot_elem->getAttribute("_kind"));
if (kind == "marginal_heatmap")
{
grm_args_t *input_args;
@@ -2323,6 +2056,12 @@ void GRPlotWidget::hist()
series_elem->setAttribute("kind", "hist");
}
}
+
+ // to get the same bars then before all bars have to exist during render call so that the linespec work properly
+ for (const auto &elem : global_root->querySelectorsAll("series_hist"))
+ {
+ elem->setAttribute("_update_required", true);
+ }
redraw();
}
@@ -2338,6 +2077,13 @@ void GRPlotWidget::barplot()
series_elem->setAttribute("kind", "barplot");
}
}
+
+ // to get the same bars then before all bars have to exist during render call so that the linespec work properly
+ for (const auto &elem : global_root->querySelectorsAll("series_barplot"))
+ {
+ elem->removeAttribute("fill_color_ind");
+ elem->setAttribute("_update_required", true);
+ }
redraw();
}
@@ -2353,6 +2099,12 @@ void GRPlotWidget::stairs()
series_elem->setAttribute("kind", "stairs");
}
}
+
+ // to get the same lines then before all lines have to exist during render call so that the linespec work properly
+ for (const auto &elem : global_root->querySelectorsAll("series_stairs"))
+ {
+ elem->setAttribute("_update_required", true);
+ }
redraw();
}
@@ -2391,6 +2143,26 @@ void GRPlotWidget::hexbin()
redraw();
}
+void GRPlotWidget::polar_line()
+{
+ if (global_root == nullptr) global_root = grm_get_document_root();
+ for (const auto &elem : global_root->querySelectorsAll("series_polar_scatter"))
+ {
+ elem->setAttribute("kind", "polar_line");
+ }
+ redraw();
+}
+
+void GRPlotWidget::polar_scatter()
+{
+ auto root = grm_get_document_root();
+ for (const auto &elem : root->querySelectorsAll("series_polar_line"))
+ {
+ elem->setAttribute("kind", "polar_scatter");
+ }
+ redraw();
+}
+
void GRPlotWidget::pdf()
{
file_export = "pdf";
@@ -2449,7 +2221,7 @@ void GRPlotWidget::extract_bounding_boxes_from_grm(QPainter &painter)
if (xmin == DBL_MAX || xmax == -DBL_MAX || ymin == DBL_MAX || ymax == -DBL_MAX)
{
- qDebug() << "skipping" << cur_child->localName().c_str();
+ if (getenv("GRM_DEBUG")) qDebug() << "skipping" << cur_child->localName().c_str();
}
else
{
@@ -2515,6 +2287,23 @@ void GRPlotWidget::highlight_current_selection(QPainter &painter)
}
painter.fillRect(rect, QBrush(QColor(255, 0, 0, 30), Qt::SolidPattern));
}
+ if (!referenced_elements.empty())
+ {
+ for (const auto &elem : referenced_elements)
+ {
+ auto rect = elem.boundingRect();
+ if (elem.get_ref() != nullptr)
+ {
+ auto bbox_xmin = static_cast(elem.get_ref()->getAttribute("_bbox_x_min"));
+ auto bbox_xmax = static_cast(elem.get_ref()->getAttribute("_bbox_x_max"));
+ auto bbox_ymin = static_cast(elem.get_ref()->getAttribute("_bbox_y_min"));
+ auto bbox_ymax = static_cast(elem.get_ref()->getAttribute("_bbox_y_max"));
+ rect = QRectF(bbox_xmin, bbox_ymin, bbox_xmax - bbox_xmin, bbox_ymax - bbox_ymin);
+ painter.drawText(rect.topLeft() + QPointF(5, 10), elem.get_ref()->localName().c_str());
+ }
+ painter.fillRect(rect, QBrush(QColor(243, 224, 59, 40), Qt::SolidPattern));
+ }
+ }
}
}
@@ -2572,6 +2361,7 @@ void GRPlotWidget::load_file_slot()
grm_load_graphics_tree(file);
global_root = grm_get_document_root();
redraw();
+ if (table_widget->isVisible()) table_widget->updateData(grm_get_render()->getContext());
#else
std::stringstream text_stream;
text_stream << "XML support not compiled in. Please recompile GRPlot with libxml2 support.";
@@ -2736,6 +2526,136 @@ void GRPlotWidget::screenChanged()
redraw();
}
+void GRPlotWidget::showContextSlot()
+{
+ if (show_context_action->isChecked())
+ {
+ auto context = grm_get_render()->getContext();
+ table_widget->updateData(context);
+ table_widget->show();
+ }
+ else
+ {
+ table_widget->hide();
+ }
+ table_widget->resize(width(), 350);
+ table_widget->move((int)(this->pos().x() + 0.5 * this->width() - 61),
+ this->pos().y() - 28 + table_widget->geometry().y());
+}
+
+void GRPlotWidget::addContextSlot()
+{
+ std::string path =
+ QFileDialog::getOpenFileName(this, "Open column data file", QDir::homePath(), "(*.dat *.csv *.xyz)")
+ .toStdString();
+ if (path.empty()) return;
+
+ // convert the data
+ if (!grm_context_data_from_file(grm_get_render()->getContext(), path))
+ {
+ fprintf(stderr, "Could not interpret the file to context data\n");
+ return;
+ }
+ auto context = grm_get_render()->getContext();
+ table_widget->updateData(context);
+}
+
+void GRPlotWidget::addGRPlotDataContextSlot()
+{
+ std::string path =
+ QFileDialog::getOpenFileName(this, "Interpret matrix as 1 column data", QDir::homePath(), "(*.dat *.csv *.xyz)")
+ .toStdString();
+ if (path.empty()) return;
+
+ // convert the data
+ if (!grm_context_data_from_file(grm_get_render()->getContext(), path, true))
+ {
+ fprintf(stderr, "Could not interpret the file to context data\n");
+ return;
+ }
+ auto context = grm_get_render()->getContext();
+ table_widget->updateData(context);
+}
+
+void GRPlotWidget::generateLinearContextSlot()
+{
+ QList fields;
+ std::vector label = {"Context-Data key:", "Min value:", "Max value", "Number of data"};
+ QDialog dialog(this);
+ QString title("Generate linear context entry");
+ dialog.setWindowTitle(title);
+ auto form = new QFormLayout;
+
+ // needed information to generate linear data for the context
+ for (int i = 0; i < 4; i++)
+ {
+ auto lineEdit = new QLineEdit(&dialog);
+ ((QLineEdit *)lineEdit)->setText("");
+ auto text_label = QString(label[i].c_str());
+ form->addRow(text_label, lineEdit);
+ fields << lineEdit;
+ }
+
+ QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
+ form->addRow(&buttonBox);
+ QObject::connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ QObject::connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
+
+ auto scrollAreaContent = new QWidget;
+ scrollAreaContent->setLayout(form);
+ auto scrollArea = new QScrollArea;
+ scrollArea = new QScrollArea;
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setWidget(scrollAreaContent);
+
+ auto groupBoxLayout = new QVBoxLayout;
+ groupBoxLayout->addWidget(scrollArea);
+ dialog.setLayout(groupBoxLayout);
+
+ if (dialog.exec() == QDialog::Accepted)
+ {
+ int n;
+ double start, end;
+ std::vector values;
+ std::vector data_vec;
+ std::shared_ptr context = grm_get_render()->getContext();
+
+ for (int i = 0; i < 4; i++)
+ {
+ auto &field = *fields[i];
+ auto value = ((QLineEdit *)fields[i])->text().toStdString();
+ if (value.empty())
+ {
+ fprintf(stderr, "All fields must be filled to generate linear context data\n");
+ return;
+ }
+ values.push_back(value);
+ }
+
+ // convert entries into linear data vec
+ try
+ {
+ start = std::stod(values[1]);
+ end = std::stod(values[2]);
+ n = std::stoi(values[3]);
+ for (int i = 0; i < n; i++)
+ {
+ data_vec.push_back(start + i * (end - start) / (n - 1));
+ }
+
+ (*context)[values[0]] = data_vec;
+ table_widget->updateData(context);
+ }
+ catch (std::invalid_argument &e)
+ {
+ fprintf(stderr, "Invalid argument for generate linear context parameter\n");
+ return;
+ }
+ }
+}
+
void GRPlotWidget::size_callback(const grm_event_t *new_size_object)
{
// TODO: Get Plot ID
@@ -2794,8 +2714,9 @@ void GRPlotWidget::processTestCommandsFile()
{
elem->setAttribute(words[n - 2].toUtf8().constData(), words[n - 1].toUtf8().constData());
}
+ auto value = words[n - 1].toUtf8().constData();
- if (strcmp(words[n - 1].toUtf8().constData(), "line") == 0)
+ if (strcmp(value, "line") == 0)
{
// to get the same lines then before all lines have to exist during render call so that the linespec
// work properly
@@ -2804,6 +2725,16 @@ void GRPlotWidget::processTestCommandsFile()
elem->setAttribute("_update_required", true);
}
}
+ if (strcmp(value, "barplot") == 0 || strcmp(value, "hist") == 0 || strcmp(value, "stairs") == 0)
+ {
+ // to get the same barplots then before all lines have to exist during render call so that the
+ // linespec work properly
+ for (const auto &elem : global_root->querySelectorsAll("series_" + std::string(value)))
+ {
+ if (strcmp(value, "barplot") == 0) elem->removeAttribute("fill_color_ind");
+ elem->setAttribute("_update_required", true);
+ }
+ }
redraw();
}
else if (words[0] == "mouseMoveEvent" && words.size() == 3)
@@ -3039,9 +2970,9 @@ void GRPlotWidget::set_current_selection(Bounding_object *p_current_selection)
this->current_selection = p_current_selection;
}
-Bounding_object *GRPlotWidget::get_current_selection()
+Bounding_object **GRPlotWidget::get_current_selection()
{
- return this->current_selection;
+ return &(this->current_selection);
}
QStringList GRPlotWidget::getCheckBoxAttributes()
@@ -3069,3 +3000,22 @@ const std::list> &GRPlotWidget::get_current_sel
{
return current_selections;
}
+
+void GRPlotWidget::setTreeUpdate(bool status)
+{
+ this->tree_update = status;
+}
+
+void GRPlotWidget::editElementAccepted()
+{
+ current_selection = nullptr;
+ mouse_move_selection = nullptr;
+ amount_scrolled = 0;
+ clicked.clear();
+ reset_pixmap();
+}
+
+void GRPlotWidget::set_referenced_elements(std::vector referenced_elements)
+{
+ this->referenced_elements = referenced_elements;
+}
diff --git a/lib/grm/grplot/grplot_widget.hxx b/lib/grm/grplot/grplot_widget.hxx
index 3b6256a4a..b9ede474b 100644
--- a/lib/grm/grplot/grplot_widget.hxx
+++ b/lib/grm/grplot/grplot_widget.hxx
@@ -17,6 +17,8 @@
class GRPlotWidget;
#include "gredit/TreeWidget.h"
#include "gredit/AddElementWidget.h"
+#include "gredit/EditElementWidget.h"
+#include "gredit/TableWidget.h"
#include "qtterm/receiver_thread.h"
#include "qtterm/grm_args_t_wrapper.h"
#include "util.hxx"
@@ -39,7 +41,7 @@ public:
void set_selected_parent(Bounding_object *parent);
Bounding_object *get_selected_parent();
void set_current_selection(Bounding_object *current_selection);
- Bounding_object *get_current_selection();
+ Bounding_object **get_current_selection();
void add_current_selection(std::unique_ptr current_selection);
std::list>::iterator
erase_current_selection(std::list>::const_iterator current_selection);
@@ -50,6 +52,11 @@ public:
QStringList getComboBoxAttributes();
void attributeSetForComboBox(const std::string &attr_type, std::shared_ptr element,
const std::string &value, const std::string &label);
+ void advancedAttributeComboBoxHandler(const std::string &cur_attr_name, std::string cur_elem_name,
+ QWidget **lineEdit);
+ void setTreeUpdate(bool status);
+ void editElementAccepted();
+ void set_referenced_elements(std::vector referenced_elements);
protected:
virtual void draw();
@@ -96,6 +103,8 @@ private slots:
void stem();
void shade();
void hexbin();
+ void polar_line();
+ void polar_scatter();
void pdf();
void png();
void jpeg();
@@ -109,6 +118,10 @@ private slots:
void add_element_slot();
void received(grm_args_t_wrapper args);
void screenChanged();
+ void showContextSlot();
+ void addContextSlot();
+ void addGRPlotDataContextSlot();
+ void generateLinearContextSlot();
private:
struct MouseState
@@ -199,7 +212,7 @@ private:
std::vector tooltips;
QTextDocument label;
Bounding_logic *bounding_logic;
- std::vector clicked;
+ std::vector clicked, referenced_elements;
Bounding_object *current_selection, *mouse_move_selection, *selected_parent;
std::list> current_selections;
bool highlightBoundingObjects;
@@ -212,10 +225,12 @@ private:
bool tree_update = true;
QSize size_hint;
QStringList check_box_attr, combo_box_attr;
+ TableWidget *table_widget;
+ EditElementWidget *edit_element_widget;
QMenuBar *menu;
QMenu *type, *algo, *export_menu, *editor_menu, *modi_menu;
- QMenu *file_menu, *configuration_menu;
+ QMenu *file_menu, *configuration_menu, *context_menu, *add_context_data;
QAction *marginalheatmapAllAct, *marginalheatmapLineAct;
QAction *sumAct, *maxAct;
QAction *lineAct, *scatterAct;
@@ -224,10 +239,12 @@ private:
QAction *plot3Act, *trisurfAct, *tricontAct, *scatter3Act;
QAction *histAct, *barplotAct, *stairsAct, *stemAct;
QAction *shadeAct, *hexbinAct;
+ QAction *polarLineAct, *polarScatterAct;
QAction *PdfAct, *PngAct, *JpegAct, *SvgAct;
QAction *show_container_action, *show_bounding_boxes_action, *save_file_action, *load_file_action, *editor_action,
*add_element_action;
QAction *moveableModeAct;
+ QAction *show_context_action, *add_context_action, *generate_linear_context_action, *add_grplot_data_context;
QCursor *csr;
void reset_pixmap();
@@ -239,8 +256,6 @@ private:
QSize sizeHint() const override;
void size_callback(const grm_event_t *);
void cmd_callback(const grm_request_event_t *);
- void advancedAttributeComboBoxHandler(const std::string &cur_attr_name, std::string cur_elem_name,
- QWidget **lineEdit);
};
#endif /* ifndef GRPLOT_WIDGET_H_INCLUDED */
diff --git a/lib/grm/grplot/makefile.mingw b/lib/grm/grplot/makefile.mingw
index 83ac82951..4160b60a9 100644
--- a/lib/grm/grplot/makefile.mingw
+++ b/lib/grm/grplot/makefile.mingw
@@ -28,7 +28,7 @@ ifeq ($(ARCHITECTURE),i686)
grplot.exe: grplot.cxx
$(CXX) -o $@ $^
else
-grplot.exe: grplot.cxx grplot_mainwindow.cxx grplot_widget.cxx util.cxx gredit/AddElementWidget.cpp gredit/Bounding_logic.cpp gredit/Bounding_object.cpp gredit/CustomTreeWidgetItem.cpp gredit/TreeWidget.cpp qtterm/grm_args_t_wrapper.cpp qtterm/receiver_thread.cpp $(GRMLIB)
+grplot.exe: grplot.cxx grplot_mainwindow.cxx grplot_widget.cxx util.cxx gredit/AddElementWidget.cpp gredit/Bounding_logic.cpp gredit/Bounding_object.cpp gredit/CustomTreeWidgetItem.cpp gredit/EditElementWidget.cpp gredit/TableWidget.cpp gredit/TreeWidget.cpp qtterm/grm_args_t_wrapper.cpp qtterm/receiver_thread.cpp $(GRMLIB)
wget https://gr-framework.org/downloads/3rdparty/qt5-runtime-Windows-$(ARCHITECTURE)-mingw81.tar.gz
tar xzf qt5-runtime-Windows-$(ARCHITECTURE)-mingw81.tar.gz
moc -DGRDIR=\"$(GRDIR)\" -Iinclude grplot_widget.hxx -o moc_grplot_widget.cxx
@@ -37,10 +37,12 @@ grplot.exe: grplot.cxx grplot_mainwindow.cxx grplot_widget.cxx util.cxx gredit/A
moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/Bounding_logic.h -o gredit/moc_Bounding_logic.cpp
moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/Bounding_object.h -o gredit/moc_Bounding_object.cpp
moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/CustomTreeWidgetItem.h -o gredit/moc_CustomTreeWidgetItem.cpp
+ moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/EditElementWidget.h -o gredit/moc_EditElementWidget.cpp
+ moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/TableWidget.h -o gredit/moc_TableWidget.cpp
moc -DGRDIR=\"$(GRDIR)\" -Iinclude gredit/TreeWidget.h -o gredit/moc_TreeWidget.cpp
moc -DGRDIR=\"$(GRDIR)\" -Iinclude qtterm/grm_args_t_wrapper.h -o qtterm/moc_grm_args_t_wrapper.cpp
moc -DGRDIR=\"$(GRDIR)\" -Iinclude qtterm/receiver_thread.h -o qtterm/moc_receiver_thread.cpp
- $(CXX) -Wl,--subsystem,console -mconsole -std=c++17 -DGRDIR=\"$(GRDIR)\" -DGR_STATIC_LIB $(INCLUDES) -Iinclude -Iinclude/QtGui -Iinclude/QtWidgets -Iinclude/QtCore -I../ -o $@ $^ moc_grplot_widget.cxx moc_grplot_mainwindow.cxx gredit/moc_AddElementWidget.cpp gredit/moc_Bounding_logic.cpp gredit/moc_Bounding_object.cpp gredit/moc_CustomTreeWidgetItem.cpp gredit/moc_TreeWidget.cpp qtterm/moc_grm_args_t_wrapper.cpp qtterm/moc_receiver_thread.cpp Qt5Gui.dll Qt5Widgets.dll Qt5Core.dll \
+ $(CXX) -Wl,--subsystem,console -mconsole -std=c++17 -DGRDIR=\"$(GRDIR)\" -DGR_STATIC_LIB $(INCLUDES) -Iinclude -Iinclude/QtGui -Iinclude/QtWidgets -Iinclude/QtCore -I../ -o $@ $^ moc_grplot_widget.cxx moc_grplot_mainwindow.cxx gredit/moc_AddElementWidget.cpp gredit/moc_Bounding_logic.cpp gredit/moc_Bounding_object.cpp gredit/moc_CustomTreeWidgetItem.cpp gredit/moc_EditElementWidget.cpp gredit/moc_TableWidget.cpp gredit/moc_TreeWidget.cpp qtterm/moc_grm_args_t_wrapper.cpp qtterm/moc_receiver_thread.cpp Qt5Gui.dll Qt5Widgets.dll Qt5Core.dll \
$(XERCESCLIBS) $(JPEGLIBS) $(FTLIBS) $(PNGLIBS) $(ZLIBS) $(QHLIBS) $(LIBS)
endif
diff --git a/lib/grm/include/grm/dom_render/InvalidValueError.hxx b/lib/grm/include/grm/dom_render/InvalidValueError.hxx
new file mode 100644
index 000000000..e899165e3
--- /dev/null
+++ b/lib/grm/include/grm/dom_render/InvalidValueError.hxx
@@ -0,0 +1,13 @@
+#ifndef GRENDER_INVALIDVALUEERROR_HXX
+#define GRENDER_INVALIDVALUEERROR_HXX
+
+#include
+#include
+
+class InvalidValueError : public std::logic_error
+{
+public:
+ EXPORT explicit InvalidValueError(const std::string &what_arg) : std::logic_error(what_arg) {}
+};
+
+#endif // GRENDER_INVALIDVALUEERROR_HXX
diff --git a/lib/grm/include/grm/dom_render/context.hxx b/lib/grm/include/grm/dom_render/context.hxx
index df51c1409..2689e5040 100644
--- a/lib/grm/include/grm/dom_render/context.hxx
+++ b/lib/grm/include/grm/dom_render/context.hxx
@@ -46,9 +46,6 @@ public:
private:
Context *context;
std::string key;
- bool intUsed();
- bool doubleUsed();
- bool stringUsed();
void increment_key(const std::string &);
public:
@@ -77,6 +74,9 @@ public:
explicit operator std::vector *();
explicit operator const std::vector *() const;
+ bool intUsed();
+ bool doubleUsed();
+ bool stringUsed();
void delete_key(const std::string &);
void use_context_key(const std::string &key, const std::string &old_key = "");
void decrement_key(const std::string &);
diff --git a/lib/grm/include/grm/dom_render/render.hxx b/lib/grm/include/grm/dom_render/render.hxx
index 6ff4cef09..a5b28abae 100644
--- a/lib/grm/include/grm/dom_render/render.hxx
+++ b/lib/grm/include/grm/dom_render/render.hxx
@@ -23,10 +23,10 @@
#define PLOT_DEFAULT_CLEAR 1
#define PLOT_DEFAULT_UPDATE 1
#define PLOT_DEFAULT_LOCATION 1
-#define PLOT_DEFAULT_SUBPLOT_MIN_X 0.0
-#define PLOT_DEFAULT_SUBPLOT_MAX_X 1.0
-#define PLOT_DEFAULT_SUBPLOT_MIN_Y 0.0
-#define PLOT_DEFAULT_SUBPLOT_MAX_Y 1.0
+#define PLOT_DEFAULT_PLOT_MIN_X 0.0
+#define PLOT_DEFAULT_PLOT_MAX_X 1.0
+#define PLOT_DEFAULT_PLOT_MIN_Y 0.0
+#define PLOT_DEFAULT_PLOT_MAX_Y 1.0
#define PLOT_DEFAULT_ROTATION 40.0
#define PLOT_DEFAULT_TILT 60.0
#define PLOT_DEFAULT_KEEP_ASPECT_RATIO 1
@@ -80,10 +80,12 @@
#define PLOT_2D_CHAR_HEIGHT 0.018
#define PLOT_POLAR_CHAR_HEIGHT 0.018
#define PLOT_DEFAULT_AXES_TICK_SIZE 0.0075
-#define DEFAULT_ASPECT_RATIO_FOR_SCALING 4.0 / 3.0
+#define DEFAULT_ASPECT_RATIO_FOR_SCALING (4.0 / 3.0)
#define PLOT_DEFAULT_ONLY_QUADRATIC_ASPECT_RATIO 0
#define MIRRORED_AXIS_DEFAULT 1
#define SCIENTIFIC_FORMAT_OPTION 2
+#define PLOT_DEFAULT_MODEL 0
+#define ERRORBAR_DEFAULT_STYLE 0
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ util ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -125,6 +127,9 @@ EXPORT int textAlignHorizontalStringToInt(const std::string &text_align_horizont
EXPORT int textAlignVerticalStringToInt(const std::string &text_align_vertical_str);
EXPORT int textEncodingStringToInt(const std::string &text_encoding_str);
EXPORT int tickOrientationStringToInt(const std::string &tick_orientation_str);
+EXPORT int errorBarStyleStringToInt(const std::string &error_bar_stylr_str);
+EXPORT int clipRegionStringToInt(const std::string &error_bar_stylr_str);
+EXPORT int resampleMethodStringToInt(const std::string &error_bar_stylr_str);
EXPORT std::string algorithmIntToString(int algorithm);
EXPORT std::string colormapIntToString(int colormap);
@@ -142,6 +147,9 @@ EXPORT std::string textAlignHorizontalIntToString(int text_align_horizontal);
EXPORT std::string textAlignVerticalIntToString(int text_align_vertical);
EXPORT std::string textEncodingIntToString(int text_encoding);
EXPORT std::string tickOrientationIntToString(int tick_orientation);
+EXPORT std::string errorBarStyleIntToString(int error_bar_style);
+EXPORT std::string clipRegionIntToString(int error_bar_style);
+EXPORT std::string resampleMethodIntToString(int error_bar_style);
EXPORT std::vector getSizeUnits();
EXPORT std::vector getColormaps();
@@ -154,6 +162,9 @@ EXPORT std::vector getTextAlignHorizontal();
EXPORT std::vector getTextAlignVertical();
EXPORT std::vector getAlgorithm();
EXPORT std::vector getModel();
+EXPORT std::vector getContextAttributes();
+
+EXPORT void addValidContextKey(std::string key);
/* ========================= classes ================================================================================ */
@@ -253,7 +264,7 @@ public:
int tick_orientation, double label_pos,
const std::shared_ptr &ext_element = nullptr);
- std::shared_ptr createTickGroup(int is_major, std::string tick_label, double value, double width,
+ std::shared_ptr createTickGroup(int is_major, const std::string &tick_label, double value, double width,
const std::shared_ptr &ext_element = nullptr);
std::shared_ptr createTick(int is_major, double value,
@@ -267,10 +278,6 @@ public:
const std::shared_ptr &extContext = nullptr,
const std::shared_ptr &extElement = nullptr);
- std::shared_ptr createDrawPolarAxes(int angle_ticks, const std::string &kind, int phiflip,
- const std::string &norm = "", double tick = 0.0, double line_width = 0.0,
- const std::shared_ptr &extElement = nullptr);
-
std::shared_ptr createPieLegend(const std::string &labels_key,
std::optional> labels,
const std::shared_ptr &extContext = nullptr,
@@ -386,13 +393,22 @@ public:
std::shared_ptr createIntegral(double int_lim_low, double int_lim_high,
const std::shared_ptr &extElement = nullptr);
- std::shared_ptr createSideRegion(std::string location,
+ std::shared_ptr createSideRegion(const std::string &location,
const std::shared_ptr &ext_element = nullptr);
std::shared_ptr createTextRegion(const std::shared_ptr &ext_element = nullptr);
std::shared_ptr createSidePlotRegion(const std::shared_ptr &ext_element = nullptr);
+ std::shared_ptr createRhoAxes(const std::shared_ptr &ext_element = nullptr);
+
+ std::shared_ptr createThetaAxes(const std::shared_ptr &ext_element = nullptr);
+
+ std::shared_ptr createAngleLine(double x, double y, const std::string &angle_label,
+ const std::shared_ptr &ext_element = nullptr);
+
+ std::shared_ptr createArcGridLine(double value, const std::shared_ptr &ext_element = nullptr);
+
//! Modifierfunctions
/* ------------------------------- setter functions ----------------------------------------------------------------*/
@@ -411,6 +427,8 @@ public:
//! Use Fallback
void setNextColor(const std::shared_ptr &element);
+ void setClipRegion(const std::shared_ptr &element, int region);
+
void setViewport(const std::shared_ptr &element, double xmin, double xmax, double ymin, double ymax);
void setWSViewport(const std::shared_ptr &element, double xmin, double xmax, double ymin, double ymax);
@@ -494,7 +512,7 @@ public:
void setProjectionType(const std::shared_ptr &element, int type);
- void setSubplot(const std::shared_ptr &element, double xmin, double xmax, double ymin, double ymax);
+ void setPlot(const std::shared_ptr &element, double xmin, double xmax, double ymin, double ymax);
void setOriginPosition(const std::shared_ptr &element, const std::string &x_org_pos,
const std::string &y_org_pos);
diff --git a/lib/grm/include/grm/import.h b/lib/grm/include/grm/import.h
index a9fcefddd..94136eb4f 100644
--- a/lib/grm/include/grm/import.h
+++ b/lib/grm/include/grm/import.h
@@ -32,5 +32,7 @@ EXPORT int grm_plot_from_file(int argc, char **argv);
#ifdef __cplusplus
}
+EXPORT int grm_context_data_from_file(const std::shared_ptr &context, const std::string &path,
+ bool interpret_matrix_as_one_column = false);
#endif
#endif // GRM_IMPORT_H_INCLUDED
diff --git a/lib/grm/include/grm/layout.hxx b/lib/grm/include/grm/layout.hxx
index 2140224e5..ec07e5c78 100644
--- a/lib/grm/include/grm/layout.hxx
+++ b/lib/grm/include/grm/layout.hxx
@@ -21,10 +21,10 @@ public:
bool isPositive();
bool isForward();
- int rowStart;
- int rowStop;
- int colStart;
- int colStop;
+ int row_start;
+ int row_stop;
+ int col_start;
+ int col_stop;
friend class Grid;
};
@@ -35,9 +35,9 @@ public:
GridElement(double absHeight, double absWidth, int absHeightPxl, int absWidthPxl, int fitParentsHeight,
int fitParentsWidth, double relativeHeight, double relativeWidth, double aspectRatio);
virtual ~GridElement();
- virtual void finalizeSubplot();
+ virtual void finalizePlot();
virtual bool isGrid();
- void setSubplot(double x1, double x2, double y1, double y2);
+ void setPlot(double x1, double x2, double y1, double y2);
void setAbsHeight(double height);
void setAbsHeightPxl(int height);
void setRelativeHeight(double height);
@@ -47,31 +47,31 @@ public:
void setAspectRatio(double ar);
void setFitParentsHeight(bool fitParentsHeight);
void setFitParentsWidth(bool fitParentsWidth);
- double *getSubplot();
- grm_args_t *subplot_args = nullptr;
-
- double *subplot;
-
- double absHeight = -1;
- double absWidth = -1;
- int absHeightPxl = -1;
- int absWidthPxl = -1;
- int fitParentsHeight = 0;
- int fitParentsWidth = 1;
- double relativeHeight = -1;
- double relativeWidth = -1;
- double aspectRatio = -1;
-
- int widthSet = 0;
- int heightSet = 0;
- int arSet = 0;
- int subplotSet = 0;
+ double *getPlot();
+ grm_args_t *plot_args = nullptr;
+
+ double *plot;
+
+ double abs_height = -1;
+ double abs_width = -1;
+ int abs_height_pxl = -1;
+ int abs_width_pxl = -1;
+ int fit_parents_height = 0;
+ int fit_parents_width = 1;
+ double relative_height = -1;
+ double relative_width = -1;
+ double aspect_ratio = -1;
+
+ int width_set = 0;
+ int height_set = 0;
+ int ar_set = 0;
+ int plot_set = 0;
int finalized = 0;
friend class Grid;
- std::shared_ptr elementInDOM = nullptr;
+ std::shared_ptr element_in_dom = nullptr;
};
class EXPORT Grid : public GridElement
@@ -90,7 +90,7 @@ public:
void ensureCellsAreGrid(Slice *slice);
GridElement *getElement(int row, int col) const;
void printGrid() const;
- virtual void finalizeSubplot() override;
+ virtual void finalizePlot() override;
bool isGrid() override;
void trim();
int getColSpan(GridElement *element);
diff --git a/lib/grm/include/grm/plot.h b/lib/grm/include/grm/plot.h
index ca7b3158e..f16599de9 100644
--- a/lib/grm/include/grm/plot.h
+++ b/lib/grm/include/grm/plot.h
@@ -65,6 +65,7 @@ EXPORT int get_focus_and_factor_from_dom(const int x1, const int y1, const int x
const int keep_aspect_ratio, double *factor_x, double *factor_y,
double *focus_x, double *focus_y,
std::shared_ptr &subplot_element);
+EXPORT std::map> grm_get_context_data();
#if !defined(NO_XERCES_C)
EXPORT std::shared_ptr grm_load_graphics_tree_schema(bool with_private_attributes = false);
diff --git a/lib/grm/src/grm/dom_render/graphics_tree/private_schema.xsd b/lib/grm/src/grm/dom_render/graphics_tree/private_schema.xsd
index 10ba424bd..677b05261 100644
--- a/lib/grm/src/grm/dom_render/graphics_tree/private_schema.xsd
+++ b/lib/grm/src/grm/dom_render/graphics_tree/private_schema.xsd
@@ -6,12 +6,18 @@
+
+
+
+
+
+
@@ -19,9 +25,14 @@
+
+
+
+
+
@@ -54,6 +65,7 @@
+
@@ -63,12 +75,14 @@
+
+
@@ -89,6 +103,7 @@
+
@@ -158,6 +173,7 @@
+
@@ -172,6 +188,7 @@
+
@@ -196,6 +213,7 @@
+
@@ -244,21 +262,40 @@
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
@@ -328,32 +365,32 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -486,11 +523,13 @@
-
+
+
+
@@ -512,17 +551,19 @@
-
-
+
+
+
+
-
-
+
+
@@ -530,12 +571,25 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -700,6 +754,7 @@
+
diff --git a/lib/grm/src/grm/dom_render/graphics_tree/schema.xsd b/lib/grm/src/grm/dom_render/graphics_tree/schema.xsd
index 42117d84c..cfac347be 100644
--- a/lib/grm/src/grm/dom_render/graphics_tree/schema.xsd
+++ b/lib/grm/src/grm/dom_render/graphics_tree/schema.xsd
@@ -9,13 +9,7 @@
-
-
-
-
-
-
@@ -29,7 +23,6 @@
-
@@ -46,10 +39,6 @@
-
-
-
-
@@ -144,7 +133,7 @@
-
+
@@ -153,11 +142,11 @@
-
+
@@ -212,13 +201,14 @@
-
-
+
+
-
+
+
@@ -232,6 +222,7 @@
+
@@ -239,7 +230,7 @@
-
+
@@ -267,6 +258,7 @@
+
@@ -323,8 +315,9 @@
-
+
+
@@ -338,11 +331,9 @@
-
-
@@ -406,11 +397,12 @@
+
-
+
@@ -549,36 +541,71 @@
-
-
+
+
-
-
-
-
-
+
+
+
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
@@ -587,6 +614,7 @@
+
@@ -595,6 +623,8 @@
+
+
@@ -679,7 +709,7 @@
-
+
@@ -690,10 +720,10 @@
-
-
+
+
-
+
@@ -705,10 +735,10 @@
-
-
+
+
-
+
@@ -717,10 +747,10 @@
-
-
+
+
-
+
@@ -733,10 +763,10 @@
-
-
+
+
-
+
@@ -770,10 +800,11 @@
+
-
+
@@ -785,7 +816,7 @@
-
+
@@ -794,6 +825,7 @@
+
@@ -830,6 +862,7 @@
+
@@ -858,7 +891,7 @@
-
+
@@ -896,6 +929,7 @@
+
@@ -905,7 +939,7 @@
-
+
@@ -961,8 +995,8 @@
-
-
+
+
@@ -971,8 +1005,8 @@
-
-
+
+
@@ -1014,29 +1048,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -1060,7 +1077,6 @@
-
@@ -1075,7 +1091,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1477,11 +1537,13 @@
-
-
+
+
+
+
diff --git a/lib/grm/src/grm/dom_render/render.cxx b/lib/grm/src/grm/dom_render/render.cxx
index 88e0a42a4..425479caa 100644
--- a/lib/grm/src/grm/dom_render/render.cxx
+++ b/lib/grm/src/grm/dom_render/render.cxx
@@ -11,6 +11,8 @@
#include
+#include
+#include
#include
#include
#include
@@ -26,6 +28,7 @@
#include
#include
#include
+#include
#include
#include "gks.h"
#include "gr.h"
@@ -67,7 +70,8 @@ ManageCustomColorIndex custom_color_index_manager;
//! This vector is used for storing element types which children get processed. Other types' children will be ignored
static std::set parent_types = {
- "axes_text_group",
+ "angle_line",
+ "arc_grid_line",
"axis",
"bar",
"central_region",
@@ -85,9 +89,9 @@ static std::set parent_types = {
"legend",
"pie_segment",
"plot",
- "polar_axes",
"polar_bar",
"marginal_heatmap_plot",
+ "rho_axes",
"root",
"series_barplot",
"series_contour",
@@ -98,13 +102,14 @@ static std::set parent_types = {
"series_imshow",
"series_isosurface",
"series_line",
- "series_nonuniformheatmap",
- "series_nonuniformpolar_heatmap",
+ "series_nonuniform_heatmap",
+ "series_nonuniform_polar_heatmap",
"series_pie",
"series_plot3",
- "series_polar",
"series_polar_heatmap",
"series_polar_histogram",
+ "series_polar_line",
+ "series_polar_scatter",
"series_quiver",
"series_scatter",
"series_scatter3",
@@ -119,18 +124,19 @@ static std::set parent_types = {
"side_region",
"side_plot_region",
"text_region",
+ "theta_axes",
"tick_group",
};
static std::set drawable_types = {
- "axes_3d", "cellarray",
+ "axes_3d", "cell_array",
"draw_arc", "draw_graphics",
"draw_image", "draw_rect",
"fill_arc", "fill_area",
"fill_rect", "grid",
"grid_3d", "isosurface_render",
"layout_grid", "layout_grid_element",
- "legend", "nonuniformcellarray",
+ "legend", "nonuniform_cell_array",
"panzoom", "polyline",
"polyline_3d", "polymarker",
"polymarker_3d", "text",
@@ -141,70 +147,66 @@ static std::set drawable_kinds = {
"contour", "contourf", "hexbin", "isosurface", "quiver", "shade", "surface", "tricontour", "trisurface", "volume",
};
-static std::set valid_context_keys = {"absolute_downwards",
- "absolute_upwards",
- "bin_counts",
- "bin_edges",
- "bin_widths",
- "bins",
- "c",
- "c_rgb",
- "c_ind",
- "classes",
- "color_ind_values",
- "color_rgb_values",
- "data",
- "directions",
- "fill_color_rgb",
- "indices",
- "int_limits_high",
- "int_limits_low",
- "labels",
- "line_color_rgb",
- "line_color_indices",
- "line_types",
- "line_widths",
- "marker_color_indices",
- "marker_sizes",
- "marker_types",
- "phi",
- "positions",
- "px",
- "py",
- "pz",
- "r",
- "relative_downwards",
- "relative_upwards",
- "scales",
- "specs",
- "theta",
- "u",
- "ups",
- "v",
- "weights",
- "x",
- "xi",
- "y",
- "y_labels",
- "z",
- "z_dims"};
+static std::set valid_context_attributes = {"absolute_downwards",
+ "absolute_upwards",
+ "bin_counts",
+ "bin_edges",
+ "bin_widths",
+ "bins",
+ "c",
+ "c_rgb",
+ "c_ind",
+ "classes",
+ "color_ind_values",
+ "color_rgb_values",
+ "data",
+ "directions",
+ "fill_color_rgb",
+ "indices",
+ "int_limits_high",
+ "int_limits_low",
+ "labels",
+ "line_color_rgb",
+ "line_color_indices",
+ "line_types",
+ "line_widths",
+ "marker_color_indices",
+ "marker_sizes",
+ "marker_types",
+ "phi",
+ "positions",
+ "px",
+ "py",
+ "pz",
+ "r",
+ "relative_downwards",
+ "relative_upwards",
+ "scales",
+ "specs",
+ "theta",
+ "u",
+ "v",
+ "weights",
+ "x",
+ "xi",
+ "y",
+ "y_labels",
+ "z",
+ "z_dims",
+ "_x_org",
+ "_y_org",
+ "_z_org"};
+
+static std::set valid_context_keys = valid_context_attributes;
static std::set polar_kinds = {
- "polar",
- "polar_histogram",
- "polar_heatmap",
- "nonuniformpolar_heatmap",
+ "nonuniform_polar_heatmap", "polar_heatmap", "polar_histogram", "polar_line", "polar_scatter",
};
static std::set kinds_3d = {
"wireframe", "surface", "plot3", "scatter3", "trisurface", "volume", "isosurface",
};
-static std::set kinds_with_possible_label = {
- "barplot", "contour", "contourf", "heatmap", "hexbin", "hist", "line",
- "marginal_heatmap", "quiver", "scatter", "shade", "stairs", "stem", "tricontour",
-};
-
static std::map symbol_to_meters_per_unit{
{"m", 1.0}, {"dm", 0.1}, {"cm", 0.01}, {"mm", 0.001}, {"in", 0.0254},
{"\"", 0.0254}, {"ft", 0.3048}, {"'", 0.0254}, {"pc", 0.0254 / 6.0}, {"pt", 0.0254 / 72.0},
@@ -228,22 +230,25 @@ static bool redraw_ws = false;
static std::map> bounding_map;
static std::map>> tick_modification_map;
-static string_map_entry_t kind_to_fmt[] = {{"line", "xys"}, {"hexbin", "xys"},
- {"polar", "xys"}, {"shade", "xys"},
- {"stem", "xys"}, {"stairs", "xys"},
- {"contour", "xyzc"}, {"contourf", "xyzc"},
- {"tricontour", "xyzc"}, {"trisurface", "xyzc"},
- {"surface", "xyzc"}, {"wireframe", "xyzc"},
- {"plot3", "xyzc"}, {"scatter", "xyzc"},
- {"scatter3", "xyzc"}, {"quiver", "xyuv"},
- {"heatmap", "xyzc"}, {"hist", "x"},
- {"barplot", "y"}, {"isosurface", "z"},
- {"imshow", "z"}, {"nonuniformheatmap", "xyzc"},
- {"polar_histogram", "x"}, {"pie", "x"},
- {"volume", "z"}, {"marginal_heatmap", "xyzc"},
- {"polar_heatmap", "xyzc"}, {"nonuniformpolar_heatmap", "xyzc"}};
-
-static string_map_t *fmt_map = string_map_new_with_data(array_size(kind_to_fmt), kind_to_fmt);
+static string_map_entry_t kind_to_fmt[] = {
+ {"line", "xys"}, {"hexbin", "xys"},
+ {"polar_line", "xys"}, {"shade", "xys"},
+ {"stem", "xys"}, {"stairs", "xys"},
+ {"contour", "xyzc"}, {"contourf", "xyzc"},
+ {"tricontour", "xyzc"}, {"trisurface", "xyzc"},
+ {"surface", "xyzc"}, {"wireframe", "xyzc"},
+ {"plot3", "xyzc"}, {"scatter", "xyzc"},
+ {"scatter3", "xyzc"}, {"quiver", "xyuv"},
+ {"heatmap", "xyzc"}, {"hist", "x"},
+ {"barplot", "y"}, {"isosurface", "z"},
+ {"imshow", "z"}, {"nonuniform_heatmap", "xyzc"},
+ {"polar_histogram", "x"}, {"pie", "x"},
+ {"volume", "z"}, {"marginal_heatmap", "xyzc"},
+ {"polar_heatmap", "xyzc"}, {"nonuniform_polar_heatmap", "xyzc"},
+ {"polar_scatter", "xys"},
+};
+
+static string_map_t *fmt_map = string_map_new_with_data(std::size(kind_to_fmt), kind_to_fmt);
enum class del_values
{
@@ -369,6 +374,10 @@ static std::map scientific_format_string_to_int{
{"textex", 2},
{"mathtex", 3},
};
+static std::map error_bar_style_string_to_int{
+ {"line", 0},
+ {"area", 1},
+};
static std::map text_align_horizontal_string_to_int{
{"normal", 0},
{"left", 1},
@@ -388,11 +397,24 @@ static std::map model_string_to_int{
{"rgb", 0},
{"hsv", 1},
};
+static std::map clip_region_string_to_int{
+ {"quadratic", 0},
+ {"elliptic", 1},
+};
+static std::map resample_method_string_to_int{
+ {"default", GKS_K_RESAMPLE_DEFAULT},
+ {"nearest", GKS_K_RESAMPLE_NEAREST},
+ {"linear", GKS_K_RESAMPLE_LINEAR},
+ {"lanczos", GKS_K_RESAMPLE_LANCZOS},
+};
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ static function header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+static void processRhoAxes(const std::shared_ptr &element, const std::shared_ptr &context);
static void processTickGroup(const std::shared_ptr &element,
const std::shared_ptr &context);
+static void processThetaAxes(const std::shared_ptr &element,
+ const std::shared_ptr &context);
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ utility functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -410,9 +432,9 @@ static bool isUniformData(const std::shared_ptr &element, const st
{
std::string x_key, y_key, kind;
kind = static_cast(element->getAttribute("kind"));
- if (str_equals_any(kind, "line", "scatter", "pie", "polar", "polar_histogram", "polar_heatmap", "imshow", "hist",
- "barplot", "stem", "stairs") ||
- std::find(kinds_3d.begin(), kinds_3d.end(), kind) != kinds_3d.end())
+ if (str_equals_any(kind, "line", "scatter", "pie", "polar_line", "polar_histogram", "polar_heatmap", "polar_scatter",
+ "imshow", "hist", "barplot", "stem", "stairs") ||
+ kinds_3d.find(kind) != kinds_3d.end())
return false;
if (kind == "heatmap" && (!element->hasAttribute("x") || !element->hasAttribute("y")))
@@ -519,7 +541,7 @@ static double getMinViewport(const std::shared_ptr &element, bool
return min_vp;
}
-static std::tuple getColorbarAttributes(std::string kind, std::shared_ptr plot)
+static std::tuple