diff --git a/docs/charts.rst b/docs/charts.rst
index 4896d9d794..d5a753c735 100644
--- a/docs/charts.rst
+++ b/docs/charts.rst
@@ -24,7 +24,7 @@ A window layer "Display chart" is shown in which you can customize the chart wit
Chart implementation
--------------------
-Charts in phpMyAdmin are drawn using `jqPlot `_ jQuery library.
+Charts in phpMyAdmin are drawn using the `Chart.js `_ library.
Examples
--------
diff --git a/package.json b/package.json
index b80fc9dc3d..d459c72774 100644
--- a/package.json
+++ b/package.json
@@ -57,10 +57,8 @@
"ts-loader": "^9.4.2",
"typescript": "~5.3.2",
"u2f-api-polyfill": "0.4.4",
- "updated-jqplot": "1.0.9",
"webpack": "^5.76.3",
- "webpack-cli": "^5.0.1",
- "webpack-concat-files-plugin": "^0.5.2"
+ "webpack-cli": "^5.0.1"
},
"devDependencies": {
"@types/jest": "^29.5.0",
diff --git a/public/themes/bootstrap/scss/_common.scss b/public/themes/bootstrap/scss/_common.scss
index 78642a3c48..2d1ddb8ec8 100644
--- a/public/themes/bootstrap/scss/_common.scss
+++ b/public/themes/bootstrap/scss/_common.scss
@@ -481,12 +481,6 @@ table#chartGrid {
padding: 3px;
margin: 0;
}
-
- div.monitorChart {
- background: #ebebeb;
- border: none;
- min-width: 1px;
- }
}
div.tabLinks {
@@ -520,10 +514,6 @@ div {
&.CodeMirror-scroll {
height: auto;
}
-
- queryProfiling {
- height: 300px;
- }
}
td.explain {
@@ -1551,17 +1541,6 @@ body .ui-widget {
z-index: 801;
}
-// over-riding jqplot-yaxis class
-.jqplot-yaxis {
- left: 0 !important;
- min-width: 25px;
- width: auto;
-}
-
-.jqplot-axis {
- overflow: hidden;
-}
-
div#page_content div {
tableslistcontainer {
margin-top: 1em;
@@ -2405,16 +2384,6 @@ body .ui-dialog {
font-weight: bold;
}
-#selection_box {
- z-index: 1000;
- height: 205px;
- position: absolute;
- background-color: #87ceeb;
- opacity: 0.4;
- filter: alpha(opacity=40);
- pointer-events: none;
-}
-
#filterQueryText {
vertical-align: baseline;
}
diff --git a/public/themes/bootstrap/scss/_jqplot.scss b/public/themes/bootstrap/scss/_jqplot.scss
deleted file mode 100644
index f3d92f879b..0000000000
--- a/public/themes/bootstrap/scss/_jqplot.scss
+++ /dev/null
@@ -1,275 +0,0 @@
-/* jqPlot */
-
-// rules for the plot target div. These will be cascaded down to all plot elements according to css rules
-.jqplot-target {
- position: relative;
- color: #222;
- font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
- font-size: 1em;
-}
-
-// rules applied to all axes
-.jqplot-axis {
- font-size: 0.75em;
-}
-
-.jqplot-xaxis {
- margin-top: 10px;
-}
-
-.jqplot-x2axis {
- margin-bottom: 10px;
-}
-
-.jqplot-yaxis {
- margin-right: 10px;
-}
-
-.jqplot-y2axis,
-.jqplot-y3axis,
-.jqplot-y4axis,
-.jqplot-y5axis,
-.jqplot-y6axis,
-.jqplot-y7axis,
-.jqplot-y8axis,
-.jqplot-y9axis,
-.jqplot-yMidAxis {
- margin-left: 10px;
- margin-right: 10px;
-}
-
-// rules applied to all axis tick divs
-.jqplot-axis-tick,
-.jqplot-xaxis-tick,
-.jqplot-yaxis-tick,
-.jqplot-x2axis-tick,
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick,
-.jqplot-yMidAxis-tick {
- position: absolute;
- white-space: pre;
-}
-
-.jqplot-xaxis-tick {
- top: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: top;
-}
-
-.jqplot-x2axis-tick {
- bottom: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: bottom;
-}
-
-.jqplot-yaxis-tick {
- right: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: right;
-
- &.jqplot-breakTick {
- right: -20px;
- margin-right: 0;
- padding: 1px 5px 1px;
- z-index: 2;
- font-size: 1.5em;
- }
-}
-
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick {
- left: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: left;
-}
-
-.jqplot-yMidAxis-tick {
- text-align: center;
- white-space: nowrap;
-}
-
-.jqplot-xaxis-label {
- margin-top: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-x2axis-label {
- margin-bottom: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yaxis-label {
- margin-right: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yMidAxis-label {
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-y2axis-label,
-.jqplot-y3axis-label,
-.jqplot-y4axis-label,
-.jqplot-y5axis-label,
-.jqplot-y6axis-label,
-.jqplot-y7axis-label,
-.jqplot-y8axis-label,
-.jqplot-y9axis-label {
- font-size: 11pt;
- margin-left: 10px;
- position: absolute;
-}
-
-.jqplot-meterGauge-tick {
- font-size: 0.75em;
- color: #999;
-}
-
-.jqplot-meterGauge-label {
- font-size: 1em;
- color: #999;
-}
-
-table {
- &.jqplot-table-legend {
- margin-top: 12px;
- margin-bottom: 12px;
- margin-left: 12px;
- margin-right: 12px;
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-
- &.jqplot-cursor-legend {
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-}
-
-td {
- &.jqplot-table-legend {
- vertical-align: middle;
- }
-
- &.jqplot-seriesToggle {
- &:hover,
- &:active {
- cursor: pointer;
- }
- }
-}
-
-.jqplot-table-legend .jqplot-series-hidden {
- text-decoration: line-through;
-}
-
-div {
- &.jqplot-table-legend-swatch-outline {
- border: 1px solid #ccc;
- padding: 1px;
- }
-
- &.jqplot-table-legend-swatch {
- width: 0;
- height: 0;
- border-top-width: 5px;
- border-bottom-width: 5px;
- border-left-width: 6px;
- border-right-width: 6px;
- border-top-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-right-style: solid;
- }
-}
-
-.jqplot-title {
- top: 0;
- left: 0;
- padding-bottom: 0.5em;
- font-size: 1.2em;
-}
-
-table.jqplot-cursor-tooltip {
- border: 1px solid #ccc;
- font-size: 0.75em;
-}
-
-.jqplot-cursor-tooltip,
-.jqplot-highlighter-tooltip,
-.jqplot-canvasOverlay-tooltip {
- border: 1px solid #ccc;
- font-size: 1em;
- white-space: nowrap;
- background: rgba(208, 208, 208, 0.8);
- padding: 1px;
-}
-
-.jqplot-point-label {
- font-size: 0.75em;
- z-index: 2;
-}
-
-td.jqplot-cursor-legend-swatch {
- vertical-align: middle;
- text-align: center;
-}
-
-div.jqplot-cursor-legend-swatch {
- width: 1.2em;
- height: 0.7em;
-}
-
-.jqplot-error {
- // Styles added to the plot target container when there is an error go here.
- text-align: center;
-}
-
-.jqplot-error-message {
- // Styling of the custom error message div goes here.
- position: relative;
- top: 46%;
- display: inline-block;
-}
-
-div {
- &.jqplot-bubble-label {
- font-size: 0.8em;
- padding-left: 2px;
- padding-right: 2px;
- color: rgb(20%, 20%, 20%);
-
- &.jqplot-bubble-label-highlight {
- background: rgba(90%, 90%, 90%, 0.7);
- }
- }
-
- &.jqplot-noData-container {
- text-align: center;
- background-color: rgba(96%, 96%, 96%, 0.3);
- }
-}
diff --git a/public/themes/bootstrap/scss/theme.scss b/public/themes/bootstrap/scss/theme.scss
index c198a90e3a..cf19f32943 100644
--- a/public/themes/bootstrap/scss/theme.scss
+++ b/public/themes/bootstrap/scss/theme.scss
@@ -5,7 +5,6 @@
@import "navigation";
@import "designer";
@import "codemirror";
-@import "jqplot";
@import "icons";
@import "reboot";
@import "tables";
diff --git a/public/themes/metro/scss/_common.scss b/public/themes/metro/scss/_common.scss
index 50367a9da1..61977561e0 100644
--- a/public/themes/metro/scss/_common.scss
+++ b/public/themes/metro/scss/_common.scss
@@ -733,11 +733,6 @@ table#chartGrid {
padding: 3px;
margin: 0;
}
-
- div.monitorChart {
- background: $th-background;
- min-width: 1px;
- }
}
div.tabLinks {
@@ -772,10 +767,6 @@ div {
&.CodeMirror-scroll {
height: auto;
}
-
- queryProfiling {
- height: 300px;
- }
}
td.explain {
@@ -2569,16 +2560,6 @@ body {
font-weight: bold;
}
-#selection_box {
- z-index: 1000;
- height: 205px;
- position: absolute;
- background-color: #87ceeb;
- opacity: 0.4;
- filter: alpha(opacity=40);
- pointer-events: none;
-}
-
#filterQueryText {
vertical-align: baseline;
}
diff --git a/public/themes/metro/scss/_jqplot.scss b/public/themes/metro/scss/_jqplot.scss
deleted file mode 100644
index b2f5c3ce00..0000000000
--- a/public/themes/metro/scss/_jqplot.scss
+++ /dev/null
@@ -1,276 +0,0 @@
-// Styles for jqPlot for the Metro theme
-
-// rules for the plot target div.
-// These will be cascaded down to all plot elements according to css rules
-.jqplot-target {
- position: relative;
- color: #222;
- font-family: $font-family-base;
- font-size: 1em;
-}
-
-// rules applied to all axes
-.jqplot-axis {
- font-size: 0.75em;
-}
-
-.jqplot-xaxis {
- margin-top: 10px;
-}
-
-.jqplot-x2axis {
- margin-bottom: 10px;
-}
-
-.jqplot-yaxis {
- margin-right: 10px;
-}
-
-.jqplot-y2axis,
-.jqplot-y3axis,
-.jqplot-y4axis,
-.jqplot-y5axis,
-.jqplot-y6axis,
-.jqplot-y7axis,
-.jqplot-y8axis,
-.jqplot-y9axis,
-.jqplot-yMidAxis {
- margin-left: 10px;
- margin-right: 10px;
-}
-
-// rules applied to all axis tick divs
-.jqplot-axis-tick,
-.jqplot-xaxis-tick,
-.jqplot-yaxis-tick,
-.jqplot-x2axis-tick,
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick,
-.jqplot-yMidAxis-tick {
- position: absolute;
- white-space: pre;
-}
-
-.jqplot-xaxis-tick {
- top: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: top;
-}
-
-.jqplot-x2axis-tick {
- bottom: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: bottom;
-}
-
-.jqplot-yaxis-tick {
- right: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: right;
-
- &.jqplot-breakTick {
- right: -20px;
- margin-right: 0;
- padding: 1px 5px 1px;
- z-index: 2;
- font-size: 1.5em;
- }
-}
-
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick {
- left: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: left;
-}
-
-.jqplot-yMidAxis-tick {
- text-align: center;
- white-space: nowrap;
-}
-
-.jqplot-xaxis-label {
- margin-top: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-x2axis-label {
- margin-bottom: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yaxis-label {
- margin-right: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yMidAxis-label {
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-y2axis-label,
-.jqplot-y3axis-label,
-.jqplot-y4axis-label,
-.jqplot-y5axis-label,
-.jqplot-y6axis-label,
-.jqplot-y7axis-label,
-.jqplot-y8axis-label,
-.jqplot-y9axis-label {
- font-size: 11pt;
- margin-left: 10px;
- position: absolute;
-}
-
-.jqplot-meterGauge-tick {
- font-size: 0.75em;
- color: #999;
-}
-
-.jqplot-meterGauge-label {
- font-size: 1em;
- color: #999;
-}
-
-table {
- &.jqplot-table-legend {
- margin-top: 12px;
- margin-bottom: 12px;
- margin-left: 12px;
- margin-right: 12px;
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-
- &.jqplot-cursor-legend {
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-}
-
-td {
- &.jqplot-table-legend {
- vertical-align: middle;
- }
-
- &.jqplot-seriesToggle {
- &:hover,
- &:active {
- cursor: pointer;
- }
- }
-}
-
-.jqplot-table-legend .jqplot-series-hidden {
- text-decoration: line-through;
-}
-
-div {
- &.jqplot-table-legend-swatch-outline {
- border: 1px solid #ccc;
- padding: 1px;
- }
-
- &.jqplot-table-legend-swatch {
- width: 0;
- height: 0;
- border-top-width: 5px;
- border-bottom-width: 5px;
- border-left-width: 6px;
- border-right-width: 6px;
- border-top-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-right-style: solid;
- }
-}
-
-.jqplot-title {
- top: 0;
- left: 0;
- padding-bottom: 0.5em;
- font-size: 1.2em;
-}
-
-table.jqplot-cursor-tooltip {
- border: 1px solid #ccc;
- font-size: 0.75em;
-}
-
-.jqplot-cursor-tooltip,
-.jqplot-highlighter-tooltip,
-.jqplot-canvasOverlay-tooltip {
- border: 1px solid #ccc;
- font-size: 0.75em;
- white-space: nowrap;
- background: rgba(208, 208, 208, 0.5);
- padding: 1px;
-}
-
-.jqplot-point-label {
- font-size: 0.75em;
- z-index: 2;
-}
-
-td.jqplot-cursor-legend-swatch {
- vertical-align: middle;
- text-align: center;
-}
-
-div.jqplot-cursor-legend-swatch {
- width: 1.2em;
- height: 0.7em;
-}
-
-// Styles added to the plot target container when there is an error go here.
-.jqplot-error {
- text-align: center;
-}
-
-// Styling of the custom error message div goes here.
-.jqplot-error-message {
- position: relative;
- top: 46%;
- display: inline-block;
-}
-
-div {
- &.jqplot-bubble-label {
- font-size: 0.8em;
- padding-left: 2px;
- padding-right: 2px;
- color: rgb(20%, 20%, 20%);
-
- &.jqplot-bubble-label-highlight {
- background: rgba(90%, 90%, 90%, 0.7);
- }
- }
-
- &.jqplot-noData-container {
- text-align: center;
- background-color: rgba(96%, 96%, 96%, 0.3);
- }
-}
diff --git a/public/themes/metro/scss/theme.scss b/public/themes/metro/scss/theme.scss
index aabb76d49b..5ec6f3b1a6 100644
--- a/public/themes/metro/scss/theme.scss
+++ b/public/themes/metro/scss/theme.scss
@@ -7,7 +7,6 @@
@import "navigation";
@import "designer";
@import "codemirror";
-@import "jqplot";
@import "icons";
@import "reboot";
@import "tables";
diff --git a/public/themes/original/scss/_common.scss b/public/themes/original/scss/_common.scss
index 13140c7000..27b89c139c 100644
--- a/public/themes/original/scss/_common.scss
+++ b/public/themes/original/scss/_common.scss
@@ -503,12 +503,6 @@ table#chartGrid {
padding: 3px;
margin: 0;
}
-
- div.monitorChart {
- background: #ebebeb;
- border: none;
- min-width: 1px;
- }
}
div.tabLinks {
@@ -2376,16 +2370,6 @@ body {
font-weight: bold;
}
-#selection_box {
- z-index: 1000;
- height: 205px;
- position: absolute;
- background-color: #87ceeb;
- opacity: 0.4;
- filter: alpha(opacity=40);
- pointer-events: none;
-}
-
#filterQueryText {
vertical-align: baseline;
}
diff --git a/public/themes/original/scss/theme.scss b/public/themes/original/scss/theme.scss
index b4eced3cb6..db7087abde 100644
--- a/public/themes/original/scss/theme.scss
+++ b/public/themes/original/scss/theme.scss
@@ -5,7 +5,6 @@
@import "navigation";
@import "../../pmahomme/scss/designer";
@import "../../pmahomme/scss/codemirror";
-@import "../../pmahomme/scss/jqplot";
@import "icons";
@import "reboot";
@import "tables";
diff --git a/public/themes/pmahomme/scss/_common.scss b/public/themes/pmahomme/scss/_common.scss
index c4740eeb70..6c16869424 100644
--- a/public/themes/pmahomme/scss/_common.scss
+++ b/public/themes/pmahomme/scss/_common.scss
@@ -667,12 +667,6 @@ table#chartGrid {
padding: 3px;
margin: 0;
}
-
- div.monitorChart {
- background: #ebebeb;
- border: none;
- min-width: 1px;
- }
}
div.tabLinks {
@@ -706,10 +700,6 @@ div {
&.CodeMirror-scroll {
height: auto;
}
-
- queryProfiling {
- height: 300px;
- }
}
td.explain {
@@ -1762,17 +1752,6 @@ body #ui-datepicker-div {
z-index: 801;
}
-// over-riding jqplot-yaxis class
-.jqplot-yaxis {
- left: 0 !important;
- min-width: 25px;
- width: auto;
-}
-
-.jqplot-axis {
- overflow: hidden;
-}
-
div#page_content div {
tableslistcontainer {
margin-top: 1em;
@@ -2533,16 +2512,6 @@ body .ui-dialog {
font-weight: bold;
}
-#selection_box {
- z-index: 1000;
- height: 205px;
- position: absolute;
- background-color: #87ceeb;
- opacity: 0.4;
- filter: alpha(opacity=40);
- pointer-events: none;
-}
-
#filterQueryText {
vertical-align: baseline;
}
diff --git a/public/themes/pmahomme/scss/_jqplot.scss b/public/themes/pmahomme/scss/_jqplot.scss
deleted file mode 100644
index f3d92f879b..0000000000
--- a/public/themes/pmahomme/scss/_jqplot.scss
+++ /dev/null
@@ -1,275 +0,0 @@
-/* jqPlot */
-
-// rules for the plot target div. These will be cascaded down to all plot elements according to css rules
-.jqplot-target {
- position: relative;
- color: #222;
- font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
- font-size: 1em;
-}
-
-// rules applied to all axes
-.jqplot-axis {
- font-size: 0.75em;
-}
-
-.jqplot-xaxis {
- margin-top: 10px;
-}
-
-.jqplot-x2axis {
- margin-bottom: 10px;
-}
-
-.jqplot-yaxis {
- margin-right: 10px;
-}
-
-.jqplot-y2axis,
-.jqplot-y3axis,
-.jqplot-y4axis,
-.jqplot-y5axis,
-.jqplot-y6axis,
-.jqplot-y7axis,
-.jqplot-y8axis,
-.jqplot-y9axis,
-.jqplot-yMidAxis {
- margin-left: 10px;
- margin-right: 10px;
-}
-
-// rules applied to all axis tick divs
-.jqplot-axis-tick,
-.jqplot-xaxis-tick,
-.jqplot-yaxis-tick,
-.jqplot-x2axis-tick,
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick,
-.jqplot-yMidAxis-tick {
- position: absolute;
- white-space: pre;
-}
-
-.jqplot-xaxis-tick {
- top: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: top;
-}
-
-.jqplot-x2axis-tick {
- bottom: 0;
- // initial position untill tick is drawn in proper place
- left: 15px;
- vertical-align: bottom;
-}
-
-.jqplot-yaxis-tick {
- right: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: right;
-
- &.jqplot-breakTick {
- right: -20px;
- margin-right: 0;
- padding: 1px 5px 1px;
- z-index: 2;
- font-size: 1.5em;
- }
-}
-
-.jqplot-y2axis-tick,
-.jqplot-y3axis-tick,
-.jqplot-y4axis-tick,
-.jqplot-y5axis-tick,
-.jqplot-y6axis-tick,
-.jqplot-y7axis-tick,
-.jqplot-y8axis-tick,
-.jqplot-y9axis-tick {
- left: 0;
- // initial position untill tick is drawn in proper place
- top: 15px;
- text-align: left;
-}
-
-.jqplot-yMidAxis-tick {
- text-align: center;
- white-space: nowrap;
-}
-
-.jqplot-xaxis-label {
- margin-top: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-x2axis-label {
- margin-bottom: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yaxis-label {
- margin-right: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yMidAxis-label {
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-y2axis-label,
-.jqplot-y3axis-label,
-.jqplot-y4axis-label,
-.jqplot-y5axis-label,
-.jqplot-y6axis-label,
-.jqplot-y7axis-label,
-.jqplot-y8axis-label,
-.jqplot-y9axis-label {
- font-size: 11pt;
- margin-left: 10px;
- position: absolute;
-}
-
-.jqplot-meterGauge-tick {
- font-size: 0.75em;
- color: #999;
-}
-
-.jqplot-meterGauge-label {
- font-size: 1em;
- color: #999;
-}
-
-table {
- &.jqplot-table-legend {
- margin-top: 12px;
- margin-bottom: 12px;
- margin-left: 12px;
- margin-right: 12px;
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-
- &.jqplot-cursor-legend {
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: 0.75em;
- }
-}
-
-td {
- &.jqplot-table-legend {
- vertical-align: middle;
- }
-
- &.jqplot-seriesToggle {
- &:hover,
- &:active {
- cursor: pointer;
- }
- }
-}
-
-.jqplot-table-legend .jqplot-series-hidden {
- text-decoration: line-through;
-}
-
-div {
- &.jqplot-table-legend-swatch-outline {
- border: 1px solid #ccc;
- padding: 1px;
- }
-
- &.jqplot-table-legend-swatch {
- width: 0;
- height: 0;
- border-top-width: 5px;
- border-bottom-width: 5px;
- border-left-width: 6px;
- border-right-width: 6px;
- border-top-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-right-style: solid;
- }
-}
-
-.jqplot-title {
- top: 0;
- left: 0;
- padding-bottom: 0.5em;
- font-size: 1.2em;
-}
-
-table.jqplot-cursor-tooltip {
- border: 1px solid #ccc;
- font-size: 0.75em;
-}
-
-.jqplot-cursor-tooltip,
-.jqplot-highlighter-tooltip,
-.jqplot-canvasOverlay-tooltip {
- border: 1px solid #ccc;
- font-size: 1em;
- white-space: nowrap;
- background: rgba(208, 208, 208, 0.8);
- padding: 1px;
-}
-
-.jqplot-point-label {
- font-size: 0.75em;
- z-index: 2;
-}
-
-td.jqplot-cursor-legend-swatch {
- vertical-align: middle;
- text-align: center;
-}
-
-div.jqplot-cursor-legend-swatch {
- width: 1.2em;
- height: 0.7em;
-}
-
-.jqplot-error {
- // Styles added to the plot target container when there is an error go here.
- text-align: center;
-}
-
-.jqplot-error-message {
- // Styling of the custom error message div goes here.
- position: relative;
- top: 46%;
- display: inline-block;
-}
-
-div {
- &.jqplot-bubble-label {
- font-size: 0.8em;
- padding-left: 2px;
- padding-right: 2px;
- color: rgb(20%, 20%, 20%);
-
- &.jqplot-bubble-label-highlight {
- background: rgba(90%, 90%, 90%, 0.7);
- }
- }
-
- &.jqplot-noData-container {
- text-align: center;
- background-color: rgba(96%, 96%, 96%, 0.3);
- }
-}
diff --git a/public/themes/pmahomme/scss/theme.scss b/public/themes/pmahomme/scss/theme.scss
index d6cbaf437b..ba1bb9ba50 100644
--- a/public/themes/pmahomme/scss/theme.scss
+++ b/public/themes/pmahomme/scss/theme.scss
@@ -5,7 +5,6 @@
@import "navigation";
@import "designer";
@import "codemirror";
-@import "jqplot";
@import "icons";
@import "reboot";
@import "tables";
diff --git a/resources/js/global.d.ts b/resources/js/global.d.ts
index e1807611ef..419113b058 100644
--- a/resources/js/global.d.ts
+++ b/resources/js/global.d.ts
@@ -48,6 +48,5 @@ interface JQuery {
interface JQueryStatic {
timepicker: any;
tablesorter: any;
- jqplot: any;
uiTableFilter: any;
}
diff --git a/resources/js/src/chart.ts b/resources/js/src/chart.ts
deleted file mode 100644
index c25ca300e2..0000000000
--- a/resources/js/src/chart.ts
+++ /dev/null
@@ -1,741 +0,0 @@
-import $ from 'jquery';
-
-/**
- * Chart type enumerations
- */
-var ChartType = {
- LINE: 'line',
- SPLINE: 'spline',
- AREA: 'area',
- BAR: 'bar',
- COLUMN: 'column',
- PIE: 'pie',
- TIMELINE: 'timeline',
- SCATTER: 'scatter'
-};
-
-/**
- * Column type enumeration
- */
-var ColumnType = {
- STRING: 'string',
- NUMBER: 'number',
- BOOLEAN: 'boolean',
- DATE: 'date'
-};
-
-/**
- * Abstract chart factory which defines the contract for chart factories
- */
-var ChartFactory = function () {
-};
-
-ChartFactory.prototype = {
- createChart: function () {
- throw new Error('createChart must be implemented by a subclass');
- }
-};
-
-/**
- * Abstract chart which defines the contract for charts
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var AbstractChart = function (elementId = undefined) {
- this.elementId = elementId;
-};
-
-AbstractChart.prototype = {
- draw: function () {
- throw new Error('draw must be implemented by a subclass');
- },
- redraw: function () {
- throw new Error('redraw must be implemented by a subclass');
- },
- destroy: function () {
- throw new Error('destroy must be implemented by a subclass');
- },
- toImageString: function () {
- throw new Error('toImageString must be implemented by a subclass');
- }
-};
-
-/**
- * Abstract representation of charts that operates on DataTable where,
- *
- * - First column provides index to the data.
- * - Each subsequent columns are of type
- *
ColumnType.NUMBER and represents a data series.
- *
- * Line chart, area chart, bar chart, column chart are typical examples.
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var BaseChart = function (elementId = undefined) {
- AbstractChart.call(this, elementId);
-};
-
-BaseChart.prototype = new AbstractChart();
-BaseChart.prototype.constructor = BaseChart;
-BaseChart.prototype.validateColumns = function (dataTable) {
- var columns = dataTable.getColumns();
- if (columns.length < 2) {
- throw new Error('Minimum of two columns are required for this chart');
- }
-
- for (var i = 1; i < columns.length; i++) {
- if (columns[i].type !== ColumnType.NUMBER) {
- throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
- }
- }
-
- return true;
-};
-
-/**
- * Abstract pie chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var PieChart = function (elementId) {
- BaseChart.call(this, elementId);
-};
-
-PieChart.prototype = new BaseChart();
-PieChart.prototype.constructor = PieChart;
-PieChart.prototype.validateColumns = function (dataTable) {
- var columns = dataTable.getColumns();
- if (columns.length > 2) {
- throw new Error('Pie charts can draw only one series');
- }
-
- return BaseChart.prototype.validateColumns.call(this, dataTable);
-};
-
-/**
- * Abstract timeline chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var TimelineChart = function (elementId) {
- BaseChart.call(this, elementId);
-};
-
-TimelineChart.prototype = new BaseChart();
-TimelineChart.prototype.constructor = TimelineChart;
-TimelineChart.prototype.validateColumns = function (dataTable) {
- var result = BaseChart.prototype.validateColumns.call(this, dataTable);
- if (result) {
- var columns = dataTable.getColumns();
- if (columns[0].type !== ColumnType.DATE) {
- throw new Error('First column of timeline chart need to be a date column');
- }
- }
-
- return result;
-};
-
-/**
- * Abstract scatter chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var ScatterChart = function (elementId) {
- BaseChart.call(this, elementId);
-};
-
-ScatterChart.prototype = new BaseChart();
-ScatterChart.prototype.constructor = ScatterChart;
-ScatterChart.prototype.validateColumns = function (dataTable) {
- var result = BaseChart.prototype.validateColumns.call(this, dataTable);
- if (result) {
- var columns = dataTable.getColumns();
- if (columns[0].type !== ColumnType.NUMBER) {
- throw new Error('First column of scatter chart need to be a numeric column');
- }
- }
-
- return result;
-};
-
-/**
- * The data table contains column information and data for the chart.
- */
-var DataTable = function () {
- var columns = [];
- var data = null;
-
- this.addColumn = function (type, name) {
- columns.push({
- 'type': type,
- 'name': name
- });
- };
-
- this.getColumns = function () {
- return columns;
- };
-
- this.setData = function (rows) {
- data = rows;
- fillMissingValues();
- };
-
- this.getData = function () {
- return data;
- };
-
- var fillMissingValues = function () {
- if (columns.length === 0) {
- throw new Error('Set columns first');
- }
-
- var row;
- for (var i = 0; i < data.length; i++) {
- row = data[i];
- if (row.length > columns.length) {
- row.splice(columns.length - 1, row.length - columns.length);
- } else if (row.length < columns.length) {
- for (var j = row.length; j < columns.length; j++) {
- row.push(null);
- }
- }
- }
- };
-};
-
-/** *****************************************************************************
- * JQPlot specific code
- ******************************************************************************/
-
-/**
- * Abstract JQplot chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotChart = function (elementId = undefined) {
- AbstractChart.call(this, elementId);
- this.plot = null;
- this.validator = null;
-};
-
-JQPlotChart.prototype = new AbstractChart();
-JQPlotChart.prototype.constructor = JQPlotChart;
-JQPlotChart.prototype.draw = function (data, options) {
- if (this.validator.validateColumns(data)) {
- this.plot = $.jqplot(this.elementId, this.prepareData(data), this
- .populateOptions(data, options));
- }
-};
-
-JQPlotChart.prototype.destroy = function () {
- if (this.plot !== null) {
- this.plot.destroy();
- }
-};
-
-JQPlotChart.prototype.redraw = function (options) {
- if (this.plot !== null) {
- this.plot.replot(options);
- }
-};
-
-JQPlotChart.prototype.toImageString = function () {
- if (this.plot !== null) {
- // @ts-ignore
- return $('#' + this.elementId).jqplotToImageStr({});
- }
-};
-
-JQPlotChart.prototype.populateOptions = function () {
- throw new Error('populateOptions must be implemented by a subclass');
-};
-
-JQPlotChart.prototype.prepareData = function () {
- throw new Error('prepareData must be implemented by a subclass');
-};
-
-/**
- * JQPlot line chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotLineChart = function (elementId = undefined) {
- JQPlotChart.call(this, elementId);
- this.validator = BaseChart.prototype;
-};
-
-JQPlotLineChart.prototype = new JQPlotChart();
-JQPlotLineChart.prototype.constructor = JQPlotLineChart;
-
-JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
- var columns = dataTable.getColumns();
- var optional = {
- axes: {
- xaxis: {
- label: columns[0].name,
- renderer: $.jqplot.CategoryAxisRenderer,
- ticks: []
- },
- yaxis: {
- label: (columns.length === 2 ? columns[1].name : 'Values'),
- labelRenderer: $.jqplot.CanvasAxisLabelRenderer
- }
- },
- highlighter: {
- show: true,
- tooltipAxes: 'y',
- formatString: '%d'
- },
- series: []
- };
- $.extend(true, optional, options);
-
- if (optional.series.length === 0) {
- for (var i = 1; i < columns.length; i++) {
- optional.series.push({
- label: columns[i].name.toString()
- });
- }
- }
-
- if (optional.axes.xaxis.ticks.length === 0) {
- var data = dataTable.getData();
- for (var j = 0; j < data.length; j++) {
- optional.axes.xaxis.ticks.push(data[j][0] !== null ? data[j][0].toString() : null);
- }
- }
-
- return optional;
-};
-
-JQPlotLineChart.prototype.prepareData = function (dataTable) {
- var data = dataTable.getData();
- var row;
- var retData = [];
- var retRow;
- for (var i = 0; i < data.length; i++) {
- row = data[i];
- for (var j = 1; j < row.length; j++) {
- retRow = retData[j - 1];
- if (retRow === undefined) {
- retRow = [];
- retData[j - 1] = retRow;
- }
-
- retRow.push(row[j]);
- }
- }
-
- return retData;
-};
-
-/**
- * JQPlot spline chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotSplineChart = function (elementId) {
- JQPlotLineChart.call(this, elementId);
-};
-
-JQPlotSplineChart.prototype = new JQPlotLineChart();
-JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
-
-JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
- var optional = {};
- var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
- options);
- var compulsory = {
- seriesDefaults: {
- rendererOptions: {
- smooth: true
- }
- }
- };
- $.extend(true, optional, opt, compulsory);
-
- return optional;
-};
-
-/**
- * JQPlot scatter chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotScatterChart = function (elementId) {
- JQPlotChart.call(this, elementId);
- this.validator = ScatterChart.prototype;
-};
-
-JQPlotScatterChart.prototype = new JQPlotChart();
-JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
-
-JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
- var columns = dataTable.getColumns();
- var optional = {
- axes: {
- xaxis: {
- label: columns[0].name
- },
- yaxis: {
- label: (columns.length === 2 ? columns[1].name : 'Values'),
- labelRenderer: $.jqplot.CanvasAxisLabelRenderer
- }
- },
- highlighter: {
- show: true,
- tooltipAxes: 'xy',
- formatString: '%d, %d'
- },
- series: []
- };
- for (var i = 1; i < columns.length; i++) {
- optional.series.push({
- label: columns[i].name.toString()
- });
- }
-
- var compulsory = {
- seriesDefaults: {
- showLine: false,
- markerOptions: {
- size: 7,
- style: 'x'
- }
- }
- };
-
- $.extend(true, optional, options, compulsory);
-
- return optional;
-};
-
-JQPlotScatterChart.prototype.prepareData = function (dataTable) {
- var data = dataTable.getData();
- var row;
- var retData = [];
- var retRow;
- for (var i = 0; i < data.length; i++) {
- row = data[i];
- if (row[0]) {
- for (var j = 1; j < row.length; j++) {
- retRow = retData[j - 1];
- if (retRow === undefined) {
- retRow = [];
- retData[j - 1] = retRow;
- }
-
- retRow.push([row[0], row[j]]);
- }
- }
- }
-
- return retData;
-};
-
-/**
- * JQPlot timeline chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotTimelineChart = function (elementId) {
- JQPlotLineChart.call(this, elementId);
- this.validator = TimelineChart.prototype;
-};
-
-JQPlotTimelineChart.prototype = new JQPlotLineChart();
-JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
-
-JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
- var optional = {
- axes: {
- xaxis: {
- tickOptions: {
- formatString: '%b %#d, %y'
- }
- }
- }
- };
- var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
- var compulsory = {
- axes: {
- xaxis: {
- renderer: $.jqplot.DateAxisRenderer
- }
- }
- };
- $.extend(true, optional, opt, compulsory);
-
- return optional;
-};
-
-JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
- var data = dataTable.getData();
- var row;
- var d;
- var retData = [];
- var retRow;
- for (var i = 0; i < data.length; i++) {
- row = data[i];
- d = row[0];
- for (var j = 1; j < row.length; j++) {
- retRow = retData[j - 1];
- if (retRow === undefined) {
- retRow = [];
- retData[j - 1] = retRow;
- }
-
- // See https://github.com/phpmyadmin/phpmyadmin/issues/14395 for the block
- if (d !== null && typeof d === 'object') {
- retRow.push([d.getTime(), row[j]]);
- } else if (typeof d === 'string') {
- d = new Date(d);
- retRow.push([d.getTime(), row[j]]);
- }
- }
- }
-
- return retData;
-};
-
-/**
- * JQPlot area chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotAreaChart = function (elementId) {
- JQPlotLineChart.call(this, elementId);
-};
-
-JQPlotAreaChart.prototype = new JQPlotLineChart();
-JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
-
-JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
- var optional = {
- seriesDefaults: {
- fillToZero: true
- }
- };
- var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
- options);
- var compulsory = {
- seriesDefaults: {
- fill: true
- }
- };
- $.extend(true, optional, opt, compulsory);
-
- return optional;
-};
-
-/**
- * JQPlot column chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotColumnChart = function (elementId) {
- JQPlotLineChart.call(this, elementId);
-};
-
-JQPlotColumnChart.prototype = new JQPlotLineChart();
-JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
-
-JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
- var optional = {
- seriesDefaults: {
- fillToZero: true
- }
- };
- var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
- options);
- var compulsory = {
- seriesDefaults: {
- renderer: $.jqplot.BarRenderer
- }
- };
- $.extend(true, optional, opt, compulsory);
-
- return optional;
-};
-
-/**
- * JQPlot bar chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotBarChart = function (elementId) {
- JQPlotLineChart.call(this, elementId);
-};
-
-JQPlotBarChart.prototype = new JQPlotLineChart();
-JQPlotBarChart.prototype.constructor = JQPlotBarChart;
-
-JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
- var columns = dataTable.getColumns();
- var optional = {
- axes: {
- yaxis: {
- label: columns[0].name,
- labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
- renderer: $.jqplot.CategoryAxisRenderer,
- ticks: []
- },
- xaxis: {
- label: (columns.length === 2 ? columns[1].name : 'Values'),
- labelRenderer: $.jqplot.CanvasAxisLabelRenderer
- }
- },
- highlighter: {
- show: true,
- tooltipAxes: 'x',
- formatString: '%d'
- },
- series: [],
- seriesDefaults: {
- fillToZero: true
- }
- };
- var compulsory = {
- seriesDefaults: {
- renderer: $.jqplot.BarRenderer,
- rendererOptions: {
- barDirection: 'horizontal'
- }
- }
- };
- $.extend(true, optional, options, compulsory);
-
- if (optional.axes.yaxis.ticks.length === 0) {
- var data = dataTable.getData();
- for (var i = 0; i < data.length; i++) {
- optional.axes.yaxis.ticks.push(data[i][0].toString());
- }
- }
-
- if (optional.series.length === 0) {
- for (var j = 1; j < columns.length; j++) {
- optional.series.push({
- label: columns[j].name.toString()
- });
- }
- }
-
- return optional;
-};
-
-/**
- * JQPlot pie chart
- *
- * @param elementId
- * id of the div element the chart is drawn in
- */
-var JQPlotPieChart = function (elementId) {
- JQPlotChart.call(this, elementId);
- this.validator = PieChart.prototype;
-};
-
-JQPlotPieChart.prototype = new JQPlotChart();
-JQPlotPieChart.prototype.constructor = JQPlotPieChart;
-
-JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
- var optional = {
- highlighter: {
- show: true,
- tooltipAxes: 'xy',
- formatString: '%s, %d',
- useAxesFormatters: false
- },
- legend: {
- renderer: $.jqplot.EnhancedPieLegendRenderer,
- },
- };
- var compulsory = {
- seriesDefaults: {
- shadow: false,
- renderer: $.jqplot.PieRenderer,
- rendererOptions: { sliceMargin: 1, showDataLabels: true }
- }
- };
- $.extend(true, optional, options, compulsory);
-
- return optional;
-};
-
-JQPlotPieChart.prototype.prepareData = function (dataTable) {
- var data = dataTable.getData();
- var row;
- var retData = [];
- for (var i = 0; i < data.length; i++) {
- row = data[i];
- retData.push([row[0], row[1]]);
- }
-
- return [retData];
-};
-
-/**
- * Chart factory that returns JQPlotCharts
- */
-var JQPlotChartFactory = function () {
-};
-
-JQPlotChartFactory.prototype = new ChartFactory();
-JQPlotChartFactory.prototype.createChart = function (type, elementId) {
- var chart = null;
- switch (type) {
- case ChartType.LINE:
- chart = new JQPlotLineChart(elementId);
- break;
- case ChartType.SPLINE:
- chart = new JQPlotSplineChart(elementId);
- break;
- case ChartType.TIMELINE:
- chart = new JQPlotTimelineChart(elementId);
- break;
- case ChartType.AREA:
- chart = new JQPlotAreaChart(elementId);
- break;
- case ChartType.BAR:
- chart = new JQPlotBarChart(elementId);
- break;
- case ChartType.COLUMN:
- chart = new JQPlotColumnChart(elementId);
- break;
- case ChartType.PIE:
- chart = new JQPlotPieChart(elementId);
- break;
- case ChartType.SCATTER:
- chart = new JQPlotScatterChart(elementId);
- break;
- }
-
- return chart;
-};
-
-declare global {
- interface Window {
- ChartType: typeof ChartType;
- ColumnType: typeof ColumnType;
- DataTable: typeof DataTable;
- JQPlotChartFactory: typeof JQPlotChartFactory;
- }
-}
-
-window.ChartType = ChartType;
-window.ColumnType = ColumnType;
-window.DataTable = DataTable;
-window.JQPlotChartFactory = JQPlotChartFactory;
diff --git a/resources/js/src/jqplot/plugins/jqplot.byteFormatter.ts b/resources/js/src/jqplot/plugins/jqplot.byteFormatter.ts
deleted file mode 100644
index e4f6146ed1..0000000000
--- a/resources/js/src/jqplot/plugins/jqplot.byteFormatter.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import $ from 'jquery';
-
-/**
- * jqplot formatter for byte values
- *
- * @package phpMyAdmin
- */
-(function ($) {
- 'use strict';
- var formatByte = function (value, index) {
- var val = value;
- var i = index;
- var units = [
- window.Messages.strB,
- window.Messages.strKiB,
- window.Messages.strMiB,
- window.Messages.strGiB,
- window.Messages.strTiB,
- window.Messages.strPiB,
- window.Messages.strEiB
- ];
- while (val >= 1024 && i <= 6) {
- val /= 1024;
- i++;
- }
-
- var format = '%.1f';
- if (Math.floor(val) === val) {
- format = '%.0f';
- }
-
- return $.jqplot.sprintf(
- format + ' ' + units[i], val
- );
- };
-
- /**
- * The index indicates what unit the incoming data will be in.
- * 0 for bytes, 1 for kilobytes and so on...
- *
- * @param index
- *
- * @return {string}
- */
- $.jqplot.byteFormatter = function (index) {
- var i = index || 0;
-
- return function (format, value) {
- var val = value;
- if (typeof val === 'number') {
- val = parseFloat(val.toString()) || 0;
-
- return formatByte(val, i);
- } else {
- return String(val);
- }
- };
- };
-}($));
diff --git a/resources/js/src/modules/chart.ts b/resources/js/src/modules/chart.ts
new file mode 100644
index 0000000000..592cac7baa
--- /dev/null
+++ b/resources/js/src/modules/chart.ts
@@ -0,0 +1,55 @@
+/**
+ * Column type enumeration
+ */
+export const ColumnType = {
+ STRING: 'string',
+ NUMBER: 'number',
+ BOOLEAN: 'boolean',
+ DATE: 'date'
+};
+
+/**
+ * The data table contains column information and data for the chart.
+ */
+export const DataTable = function () {
+ const columns = [];
+ let data = null;
+
+ this.addColumn = function (type, name) {
+ columns.push({
+ 'type': type,
+ 'name': name
+ });
+ };
+
+ this.getColumns = function () {
+ return columns;
+ };
+
+ this.setData = function (rows) {
+ data = rows;
+ fillMissingValues();
+ };
+
+ this.getData = function () {
+ return data;
+ };
+
+ const fillMissingValues = function () {
+ if (columns.length === 0) {
+ throw new Error('Set columns first');
+ }
+
+ let row;
+ for (let i = 0; i < data.length; i++) {
+ row = data[i];
+ if (row.length > columns.length) {
+ row.splice(columns.length - 1, row.length - columns.length);
+ } else if (row.length < columns.length) {
+ for (let j = row.length; j < columns.length; j++) {
+ row.push(null);
+ }
+ }
+ }
+ };
+};
diff --git a/resources/js/src/modules/functions/chartByteFormatter.ts b/resources/js/src/modules/functions/chartByteFormatter.ts
new file mode 100644
index 0000000000..d2893a2758
--- /dev/null
+++ b/resources/js/src/modules/functions/chartByteFormatter.ts
@@ -0,0 +1,49 @@
+function formatByte (value, index) {
+ let val = value;
+ let i = index;
+ const units = [
+ window.Messages.strB,
+ window.Messages.strKiB,
+ window.Messages.strMiB,
+ window.Messages.strGiB,
+ window.Messages.strTiB,
+ window.Messages.strPiB,
+ window.Messages.strEiB,
+ ];
+ while (val >= 1024 && i <= 6) {
+ val /= 1024;
+ i++;
+ }
+
+ let format = '%.1f';
+ if (Math.floor(val) === val) {
+ format = '%.0f';
+ }
+
+ return window.sprintf(
+ format + ' ' + units[i], val
+ );
+}
+
+/**
+ * The index indicates what unit the incoming data will be in.
+ * 0 for bytes, 1 for kilobytes and so on...
+ *
+ * @param index
+ *
+ * @return {string}
+ */
+export default function chartByteFormatter (index) {
+ const i = index || 0;
+
+ return function (format, value) {
+ let val = value;
+ if (typeof val === 'number') {
+ val = parseFloat(val.toString()) || 0;
+
+ return formatByte(val, i);
+ } else {
+ return String(val);
+ }
+ };
+}
diff --git a/resources/js/src/modules/functions/createProfilingChart.ts b/resources/js/src/modules/functions/createProfilingChart.ts
index cb92c36470..6d1c3778b2 100644
--- a/resources/js/src/modules/functions/createProfilingChart.ts
+++ b/resources/js/src/modules/functions/createProfilingChart.ts
@@ -1,4 +1,4 @@
-import $ from 'jquery';
+import { CommonParams } from '../common.ts';
/**
* Creates a Profiling Chart. Used in sql.js
@@ -10,63 +10,22 @@ import $ from 'jquery';
* @return {object}
*/
export default function createProfilingChart (target, data) {
- // create the chart
- var factory = new window.JQPlotChartFactory();
- var chart = factory.createChart(window.ChartType.PIE, target);
-
- // create the data table and add columns
- var dataTable = new window.DataTable();
- dataTable.addColumn(window.ColumnType.STRING, '');
- dataTable.addColumn(window.ColumnType.NUMBER, '');
- dataTable.setData(data);
-
- var windowWidth = $(window).width();
- var location = 's';
- if (windowWidth > 768) {
- location = 'se';
- }
-
- // draw the chart and return the chart object
- chart.draw(dataTable, {
- seriesDefaults: {
- rendererOptions: {
- showDataLabels: true
- }
- },
- highlighter: {
- tooltipLocation: 'se',
- sizeAdjust: 0,
- tooltipAxes: 'pieref',
- formatString: '%s, %.9Ps'
- },
- legend: {
- show: true,
- location: location,
- rendererOptions: {
- numberColumns: 2
- }
- },
- // from https://web.archive.org/web/20190321233412/http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines
- seriesColors: [
- '#fce94f',
- '#fcaf3e',
- '#e9b96e',
- '#8ae234',
- '#729fcf',
- '#ad7fa8',
- '#ef2929',
- '#888a85',
- '#c4a000',
- '#ce5c00',
- '#8f5902',
- '#4e9a06',
- '#204a87',
- '#5c3566',
- '#a40000',
- '#babdb6',
- '#2e3436'
- ]
+ const lang = CommonParams.get('lang');
+ const numberFormat = new Intl.NumberFormat(lang.replace('_', '-'), {
+ style: 'unit',
+ unit: 'second',
+ unitDisplay: 'long',
+ notation: 'engineering',
});
- return chart;
+ return new window.Chart(target, {
+ type: 'pie',
+ data: { labels: data.map(row => row[0]), datasets: [{ data: data.map(row => row[1]) }] },
+ options: {
+ plugins: {
+ legend: { position: 'right' },
+ tooltip: { callbacks: { label: context => context.parsed ? numberFormat.format(context.parsed) : '' } },
+ },
+ },
+ });
}
diff --git a/resources/js/src/server/status/monitor.ts b/resources/js/src/server/status/monitor.ts
index 955cd0b1f5..36653233ea 100644
--- a/resources/js/src/server/status/monitor.ts
+++ b/resources/js/src/server/status/monitor.ts
@@ -7,6 +7,7 @@ import createProfilingChart from '../../modules/functions/createProfilingChart.t
import { escapeHtml } from '../../modules/functions/escape.ts';
import getImageTag from '../../modules/functions/getImageTag.ts';
import isStorageSupported from '../../modules/functions/isStorageSupported.ts';
+import chartByteFormatter from '../../modules/functions/chartByteFormatter.ts';
/**
* @fileoverview Javascript functions used in server status monitor page
@@ -252,12 +253,6 @@ AJAX.registerOnload('server/status/monitor.js', function () {
}
};
- // time span selection
- var selectionTimeDiff = [];
- var selectionStartX;
- var selectionStartY;
- var drawTimeSpan = false;
-
/* Add OS specific system info charts to the preset chart list */
switch (serverOs) {
case 'WINNT':
@@ -1185,8 +1180,8 @@ AJAX.registerOnload('server/status/monitor.js', function () {
$.each(runtime.charts, function (key, chartObj) {
for (var i = 0, l = chartObj.nodes.length; i < l; i++) {
oldData[chartObj.nodes[i].dataPoint] = [];
- for (var j = 0, ll = chartObj.chart.series[i].data.length; j < ll; j++) {
- oldData[chartObj.nodes[i].dataPoint].push([chartObj.chart.series[i].data[j].x, chartObj.chart.series[i].data[j].y]);
+ for (var j = 0, ll = chartObj.chart.data.datasets[i].data.length; j < ll; j++) {
+ oldData[chartObj.nodes[i].dataPoint].push([chartObj.chart.data.datasets[i].data[j].x, chartObj.chart.data.datasets[i].data[j].y]);
}
}
});
@@ -1230,7 +1225,6 @@ AJAX.registerOnload('server/status/monitor.js', function () {
},
axes: {
xaxis: {
- renderer: $.jqplot.DateAxisRenderer,
tickOptions: {
formatString: '%H:%M:%S',
showGridline: false
@@ -1270,11 +1264,11 @@ AJAX.registerOnload('server/status/monitor.js', function () {
) {
settings.stackSeries = true;
settings.axes.yaxis.tickOptions = {
- formatter: $.jqplot.byteFormatter(2) // MiB
+ formatter: chartByteFormatter(2) // MiB
};
} else if (settings.title === window.Messages.strTraffic) {
settings.axes.yaxis.tickOptions = {
- formatter: $.jqplot.byteFormatter(1) // KiB
+ formatter: chartByteFormatter(1) // KiB
};
} else if (settings.title === window.Messages.strQuestions ||
settings.title === window.Messages.strConnections
@@ -1282,11 +1276,11 @@ AJAX.registerOnload('server/status/monitor.js', function () {
settings.axes.yaxis.tickOptions = {
formatter: function (format, val) {
if (Math.abs(val) >= 1000000) {
- return $.jqplot.sprintf('%.3g M', val / 1000000);
+ return window.sprintf('%.3g M', val / 1000000);
} else if (Math.abs(val) >= 1000) {
- return $.jqplot.sprintf('%.3g k', val / 1000);
+ return window.sprintf('%.3g k', val / 1000);
} else {
- return $.jqplot.sprintf('%d', val);
+ return window.sprintf('%d', val);
}
}
};
@@ -1294,7 +1288,7 @@ AJAX.registerOnload('server/status/monitor.js', function () {
settings.series = chartObj.series;
- if ($('#' + 'gridchart' + runtime.chartAI).length === 0) {
+ if ($('#' + 'gridChartCanvas' + runtime.chartAI).length === 0) {
var numCharts = $('#chartGrid').find('.monitorChart').length;
if (numCharts === 0 || (numCharts % monitorSettings.columns === 0)) {
@@ -1306,11 +1300,10 @@ AJAX.registerOnload('server/status/monitor.js', function () {
}
$('#chartGrid').find('tr').last().append(
- ' | '
+ '' +
+ ' ' +
+ ' ' +
+ ' | '
);
}
@@ -1369,115 +1362,84 @@ AJAX.registerOnload('server/status/monitor.js', function () {
};
}
- chartObj.chart = $.jqplot('gridchart' + runtime.chartAI, series, settings);
- // remove [0,0] after plotting
- for (i in chartObj.chart.series) {
- chartObj.chart.series[i].data.shift();
+ const datasets = [];
+ for (let i = 0; i < series.length; i++) {
+ const dataset = {
+ label: settings.series[i].label,
+ data: [],
+ fill: settings.stackSeries ? 'start' : false,
+ tension: 0.3,
+ };
+ datasets.push(dataset);
}
- var $legend = $('').css('padding', '0.5em');
- for (i in chartObj.chart.series) {
- $legend.append(
- $('').append(
- $('').css({
- width: '1em',
- height: '1em',
- background: chartObj.chart.seriesColors[i]
- }).addClass('float-start')
- ).append(
- $('
').text(
- chartObj.chart.series[i].label
- ).addClass('float-start')
- ).append(
- $('
')
- ).addClass('float-start')
- );
- }
+ chartObj.chart = new window.Chart(
+ 'gridChartCanvas' + runtime.chartAI,
+ {
+ type: 'line',
+ data: { labels: [], datasets: datasets },
+ options: {
+ locale: CommonParams.get('lang').replace('_', '-'),
+ maintainAspectRatio: false,
+ plugins: {
+ title: { display: true, text: settings.title },
+ legend: { display: true, position: 'bottom' },
+ },
+ interaction: { mode: 'index' },
+ scales: {
+ // @ts-ignore
+ x: {
+ type: 'time',
+ ticks: { maxTicksLimit: 5 },
+ },
+ y: {
+ stacked: !! settings.stackSeries,
+ suggestedMin: settings.axes.yaxis.min,
+ suggestedMax: settings.axes.yaxis.max,
+ ticks: {
+ stepSize: settings.axes.yaxis.tickInterval,
+ callback: function (value, index, ticks) {
+ if (settings.axes.yaxis?.tickOptions?.formatString) {
+ return window.sprintf(settings.axes.yaxis.tickOptions.formatString, value);
+ }
- $('#gridchart' + runtime.chartAI)
- .parent()
- .append($legend);
+ if (settings.axes.yaxis?.tickOptions?.formatter) {
+ return settings.axes.yaxis.tickOptions.formatter(null, value);
+ }
+
+ // @ts-ignore
+ return window.Chart.Ticks.formatters.numeric.apply(this, [value, index, ticks]);
+ },
+ },
+ },
+ },
+ onClick: function (event) {
+ if (editMode) {
+ return;
+ }
+
+ // @ts-ignore
+ const minDate = new Date(event.chart.scales.x.ticks[0].value);
+ // @ts-ignore
+ const maxDate = new Date(event.chart.scales.x.ticks[4].value);
+ getLogAnalyseDialog(minDate, maxDate);
+ },
+ },
+ },
+ );
if (initialize !== true) {
runtime.charts['c' + runtime.chartAI] = chartObj;
buildRequiredDataList();
}
- // time span selection
- $('#gridchart' + runtime.chartAI).on('jqplotMouseDown', function (ev, gridpos, datapos) {
- drawTimeSpan = true;
- selectionTimeDiff.push(datapos.xaxis);
- if ($('#selection_box').length) {
- $('#selection_box').remove();
- }
-
- var selectionBox = $('
');
- // eslint-disable-next-line compat/compat
- $(document.body).append(selectionBox);
- selectionStartX = ev.pageX;
- selectionStartY = ev.pageY;
- selectionBox
- .attr({ id: 'selection_box' })
- .css({
- top: selectionStartY - gridpos.y,
- left: selectionStartX
- })
- .fadeIn();
- });
-
- $('#gridchart' + runtime.chartAI).on('jqplotMouseUp', function (ev, gridpos, datapos) {
- if (! drawTimeSpan || editMode) {
- return;
- }
-
- selectionTimeDiff.push(datapos.xaxis);
-
- if (selectionTimeDiff[1] <= selectionTimeDiff[0]) {
- selectionTimeDiff = [];
-
- return;
- }
-
- // get date from timestamp
- var min = new Date(Math.ceil(selectionTimeDiff[0]));
- var max = new Date(Math.ceil(selectionTimeDiff[1]));
- getLogAnalyseDialog(min, max);
- selectionTimeDiff = [];
- drawTimeSpan = false;
- });
-
- $('#gridchart' + runtime.chartAI).on('jqplotMouseMove', function (ev) {
- if (! drawTimeSpan || editMode) {
- return;
- }
-
- if (selectionStartX !== undefined) {
- $('#selection_box')
- .css({
- width: Math.ceil(ev.pageX - selectionStartX)
- })
- .fadeIn();
- }
- });
-
- $('#gridchart' + runtime.chartAI).on('jqplotMouseLeave', function () {
- drawTimeSpan = false;
- });
-
- // eslint-disable-next-line compat/compat
- $(document.body).on('mouseup', function () {
- if ($('#selection_box').length) {
- $('#selection_box').remove();
- }
- });
-
// Edit, Print icon only in edit mode
$('#chartGrid').find('div svg').find('*[zIndex=20], *[zIndex=21], *[zIndex=19]').toggle(editMode);
runtime.chartAI++;
}
- function getLogAnalyseDialog (min, max) {
+ function getLogAnalyseDialog (min: Date, max: Date) {
var $logAnalyseDialog = $('#logAnalyseDialog');
var $dateStart = $logAnalyseDialog.find('input[name="dateStart"]');
var $dateEnd = $logAnalyseDialog.find('input[name="dateEnd"]');
@@ -1535,7 +1497,7 @@ AJAX.registerOnload('server/status/monitor.js', function () {
$dateEnd.datepicker('setDate', max);
}
- function loadLog (type, min, max) {
+ function loadLog (type: string, min: Date, max: Date) {
var dateStart = Date.parse($('#logAnalyseDialog').find('input[name="dateStart"]').datepicker('getDate').toString()) || min;
var dateEnd = Date.parse($('#logAnalyseDialog').find('input[name="dateEnd"]').datepicker('getDate').toString()) || max;
@@ -1591,7 +1553,6 @@ AJAX.registerOnload('server/status/monitor.js', function () {
runtime.xmax += diff;
}
- // elem.chart.xAxis[0].setExtremes(runtime.xmin, runtime.xmax, false);
/* Calculate y value */
// If transform function given, use it
@@ -1630,7 +1591,7 @@ AJAX.registerOnload('server/status/monitor.js', function () {
// Set y value, if defined
if (value !== undefined) {
- elem.chart.series[j].data.push([chartData.x, value]);
+ elem.chart.data.datasets[j].data.push({ x: chartData.x, y: value });
if (value > elem.maxYLabel) {
elem.maxYLabel = value;
} else if (elem.maxYLabel === 0) {
@@ -1638,15 +1599,15 @@ AJAX.registerOnload('server/status/monitor.js', function () {
}
// free old data point values and update maxYLabel
- if (elem.chart.series[j].data.length > runtime.gridMaxPoints &&
- elem.chart.series[j].data[0][0] < runtime.xmin
+ if (elem.chart.data.datasets[j].data.length > runtime.gridMaxPoints &&
+ elem.chart.data.datasets[j].data[0].x < runtime.xmin
) {
// check if the next freeable point is highest
- if (elem.maxYLabel <= elem.chart.series[j].data[0][1]) {
- elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints);
- elem.maxYLabel = getMaxYLabel(elem.chart.series[j].data);
+ if (elem.maxYLabel <= elem.chart.data.datasets[j].data[0].y) {
+ elem.chart.data.datasets[j].data.splice(0, elem.chart.data.datasets[j].data.length - runtime.gridMaxPoints);
+ elem.maxYLabel = getMaxYLabel(elem.chart.data.datasets[j].data);
} else {
- elem.chart.series[j].data.splice(0, elem.chart.series[j].data.length - runtime.gridMaxPoints);
+ elem.chart.data.datasets[j].data.splice(0, elem.chart.data.datasets[j].data.length - runtime.gridMaxPoints);
}
}
@@ -1661,7 +1622,7 @@ AJAX.registerOnload('server/status/monitor.js', function () {
// update chart options
// keep ticks number/positioning consistent while refreshrate changes
var tickInterval = (runtime.xmax - runtime.xmin) / 5;
- elem.chart.axes.xaxis.ticks = [
+ elem.chart.data.labels = [
(runtime.xmax - tickInterval * 4),
(runtime.xmax - tickInterval * 3),
(runtime.xmax - tickInterval * 2),
@@ -1673,20 +1634,22 @@ AJAX.registerOnload('server/status/monitor.js', function () {
elem.title !== window.Messages.strQueryCacheEfficiency &&
elem.title !== window.Messages.strSystemMemory &&
elem.title !== window.Messages.strSystemSwap
+ && elem.maxYLabel > 0
) {
- elem.chart.axes.yaxis.max = Math.ceil(elem.maxYLabel * 1.1);
- elem.chart.axes.yaxis.tickInterval = Math.ceil(elem.maxYLabel * 1.1 / 5);
- } else if (elem.title === window.Messages.strSystemMemory ||
- elem.title === window.Messages.strSystemSwap
+ elem.chart.options.scales.y.max = Math.ceil(elem.maxYLabel * 1.1);
+ elem.chart.options.scales.y.ticks.stepSize = Math.ceil(elem.maxYLabel * 1.1 / 5);
+ } else if (
+ (elem.title === window.Messages.strSystemMemory || elem.title === window.Messages.strSystemSwap)
+ && total > 0
) {
- elem.chart.axes.yaxis.max = Math.ceil(total * 1.1 / 100) * 100;
- elem.chart.axes.yaxis.tickInterval = Math.ceil(total * 1.1 / 5);
+ elem.chart.options.scales.y.max = Math.ceil(total * 1.1 / 100) * 100;
+ elem.chart.options.scales.y.ticks.stepSize = Math.ceil(total * 1.1 / 5);
}
i++;
if (runtime.redrawCharts) {
- elem.chart.replot();
+ elem.chart.update('none');
}
});
@@ -1696,13 +1659,13 @@ AJAX.registerOnload('server/status/monitor.js', function () {
});
}
- /* Function to get highest plotted point's y label, to scale the chart,
- * TODO: make jqplot's autoscale:true work here
+ /**
+ * Function to get the highest plotted point's y label, to scale the chart.
*/
function getMaxYLabel (dataValues) {
- var maxY = dataValues[0][1];
+ var maxY = dataValues[0].y;
$.each(dataValues, function (k, v) {
- maxY = (v[1] > maxY) ? v[1] : maxY;
+ maxY = (v.y > maxY) ? v.y : maxY;
});
return maxY;
@@ -2247,7 +2210,7 @@ AJAX.registerOnload('server/status/monitor.js', function () {
},
width: 'auto',
height: 'auto',
- resizable: false,
+ resizable: true,
// @ts-ignore
buttons: dlgBtns,
close: function () {
@@ -2383,23 +2346,23 @@ AJAX.registerOnload('server/status/monitor.js', function () {
$('#queryAnalyzerDialog').find('div.placeHolder td.chart').append(
'
' + window.Messages.strProfilingResults + ' ' + $('#profiling_docu').html() + ' ' +
'(
' + window.Messages.strTable + ',
' + window.Messages.strChart + ')
' +
- numberTable + '
');
+ numberTable + '
');
$('#queryAnalyzerDialog').find('div.placeHolder a[href="#showNums"]').on('click', function () {
- $('#queryAnalyzerDialog').find('#queryProfiling').hide();
+ $('#queryAnalyzerDialog').find('#queryProfilingCanvas').hide();
$('#queryAnalyzerDialog').find('table.queryNums').show();
return false;
});
$('#queryAnalyzerDialog').find('div.placeHolder a[href="#showChart"]').on('click', function () {
- $('#queryAnalyzerDialog').find('#queryProfiling').show();
+ $('#queryAnalyzerDialog').find('#queryProfilingCanvas').show();
$('#queryAnalyzerDialog').find('table.queryNums').hide();
return false;
});
- profilingChart = createProfilingChart('queryProfiling', chartData);
+ profilingChart = createProfilingChart('queryProfilingCanvas', chartData);
}
});
diff --git a/resources/js/src/table/chart.ts b/resources/js/src/table/chart.ts
index c44c1c59de..f6d32050b4 100644
--- a/resources/js/src/table/chart.ts
+++ b/resources/js/src/table/chart.ts
@@ -3,6 +3,7 @@ import { AJAX } from '../modules/ajax.ts';
import { Functions } from '../modules/functions.ts';
import { ajaxRemoveMessage, ajaxShowMessage } from '../modules/ajax-message.ts';
import { escapeHtml } from '../modules/functions/escape.ts';
+import { ColumnType, DataTable } from '../modules/chart.ts';
var chartData = {};
var tempChartTitle;
@@ -72,20 +73,20 @@ function queryChart (data, columnNames, settings) {
};
// create the data table and add columns
- var dataTable = new window.DataTable();
+ const dataTable = new DataTable();
if (settings.type === 'timeline') {
- dataTable.addColumn(window.ColumnType.DATE, columnNames[settings.mainAxis]);
+ dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]);
} else if (settings.type === 'scatter') {
- dataTable.addColumn(window.ColumnType.NUMBER, columnNames[settings.mainAxis]);
+ dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]);
} else {
- dataTable.addColumn(window.ColumnType.STRING, columnNames[settings.mainAxis]);
+ dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]);
}
var i;
var values = [];
if (settings.seriesColumn === null) {
$.each(settings.selectedSeries, function (index, element) {
- dataTable.addColumn(window.ColumnType.NUMBER, columnNames[element]);
+ dataTable.addColumn(ColumnType.NUMBER, columnNames[element]);
});
// set data to the data table
@@ -131,7 +132,7 @@ function queryChart (data, columnNames, settings) {
}
$.each(seriesNames, function (seriesName) {
- dataTable.addColumn(window.ColumnType.NUMBER, seriesName);
+ dataTable.addColumn(ColumnType.NUMBER, seriesName);
});
var valueMap = {};
diff --git a/resources/js/src/table/zoom_plot_jqplot.ts b/resources/js/src/table/zoom_search.ts
similarity index 99%
rename from resources/js/src/table/zoom_plot_jqplot.ts
rename to resources/js/src/table/zoom_search.ts
index 687985b8c6..bf85d5e5e8 100644
--- a/resources/js/src/table/zoom_plot_jqplot.ts
+++ b/resources/js/src/table/zoom_search.ts
@@ -109,7 +109,7 @@ function getType (field) {
/**
* Unbind all event handlers before tearing down a page
*/
-AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () {
+AJAX.registerTeardown('table/zoom_search.js', function () {
$('#tableid_0').off('change');
$('#tableid_1').off('change');
$('#tableid_2').off('change');
@@ -120,7 +120,7 @@ AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () {
$('button.button-reset').off('click');
});
-AJAX.registerOnload('table/zoom_plot_jqplot.js', function () {
+AJAX.registerOnload('table/zoom_search.js', function () {
let currentChart = null;
var searchedDataKey = null;
var xLabel = ($('#tableid_0').val() as string);
diff --git a/resources/templates/server/status/monitor/index.twig b/resources/templates/server/status/monitor/index.twig
index 98024d95fe..db592f80d9 100644
--- a/resources/templates/server/status/monitor/index.twig
+++ b/resources/templates/server/status/monitor/index.twig
@@ -74,7 +74,7 @@
{{ t("Your browser will refresh all displayed charts in a regular interval. You may add charts and change the refresh rate under 'Settings', or remove any chart using the cog icon on each respective chart.") }}
- {{ t('To display queries from the logs, select the relevant time span on any chart by holding down the left mouse button and panning over the chart. Once confirmed, this will load a table of grouped queries, there you may click on any occurring SELECT statements to further analyze them.') }}
+ {{ t('To display queries from the logs, click on any chart. Once confirmed, this will load a table of grouped queries, there you may click on any occurring SELECT statements to further analyze them.') }}
{{ get_image('s_attention') }}
@@ -213,7 +213,7 @@
-