The following issues were fixed in Graph Visualiser:

1) Allow the user to set the row limit and chart line width.
2) Zoom should only be applied to X-axis, not both.
3) On clicking the 'Generate' button, the chart should return to its original zoom level.
4) Negative values are not displayed.

refs #7485
This commit is contained in:
Akshay Joshi 2022-06-23 14:52:11 +05:30
parent 1b9d219988
commit 2556771c32
12 changed files with 60 additions and 11 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -201,6 +201,9 @@ Expand the *Graphs* node to specify your Graphs display preferences.
:alt: Preferences dialog dashboard graph options
:align: center
* Use the *Chart line width* field to specify the width of the lines on the
line chart.
* When the *Show graph data points?* switch is set to *True*, data points will
be visible on graph lines.
@ -369,6 +372,16 @@ a graphical EXPLAIN.
* When the *Verbose output?* switch is set to *True*, graphical explain details
will include extended information about the query execution plan.
.. image:: images/preferences_graph_visualiser.png
:alt: Preferences dialog sqleditor graph visualiser section
:align: center
Use the fields on the *Graph Visualiser* panel to specify the settings
related to graphs.
* Use the *Row Limit* field to specify the maximum number of rows that will
be plotted on a chart.
.. image:: images/preferences_sql_options.png
:alt: Preferences dialog sqleditor options section
:align: center

View File

@ -174,6 +174,14 @@ class DashboardModule(PgAdminModule):
'details')
)
self.graph_line_border_width = self.graphs_preference.register(
'graphs', 'graph_line_border_width',
gettext("Chart line width"), 'integer',
1, min_val=1, max_val=10,
category_label=PREF_LABEL_DISPLAY,
help_str=gettext('Set the width of the lines on the line chart.')
)
def get_exposed_url_endpoints(self):
"""
Returns:

View File

@ -233,6 +233,7 @@ export default function Graphs({preferences, sid, did, pageVisible, enablePoll=t
errorMsg={errorMsg}
showTooltip={preferences['graph_mouse_track']}
showDataPoints={preferences['graph_data_points']}
lineBorderWidth={preferences['graph_line_border_width']}
isDatabase={did > 0}
/>
}
@ -265,6 +266,9 @@ export function GraphsWrapper(props) {
point: {
radius: props.showDataPoints ? DATA_POINT_SIZE : 0,
},
line: {
borderWidth: props.lineBorderWidth,
},
},
plugins: {
legend: {
@ -289,8 +293,11 @@ export function GraphsWrapper(props) {
x: {
reverse: true,
},
y: {
min: 0,
}
},
}), [props.showTooltip, props.showDataPoints]);
}), [props.showTooltip, props.showDataPoints, props.lineBorderWidth]);
const updateOptions = useMemo(()=>({duration: 0}), []);
const onInitCallback = useCallback(
@ -353,5 +360,6 @@ GraphsWrapper.propTypes = {
errorMsg: PropTypes.string,
showTooltip: PropTypes.bool.isRequired,
showDataPoints: PropTypes.bool.isRequired,
lineBorderWidth: PropTypes.number.isRequired,
isDatabase: PropTypes.bool.isRequired,
};

View File

@ -47,7 +47,6 @@ const defaultOptions = {
elements: {
line: {
tension: 0,
borderWidth: 2,
fill: false,
},
},
@ -66,7 +65,6 @@ const defaultOptions = {
},
},
y: {
min: 0,
ticks: {
callback: function(label) {
if (Math.floor(label) === label) {

View File

@ -1089,11 +1089,11 @@ def fetch(trans_id, fetch_all=None):
@blueprint.route(
'/fetch_all_from_start/<int:trans_id>', methods=["GET"],
'/fetch_all_from_start/<int:trans_id>/<int:limit>', methods=["GET"],
endpoint='fetch_all_from_start'
)
@login_required
def fetch_all_from_start(trans_id):
def fetch_all_from_start(trans_id, limit=-1):
"""
This function is used to fetch all the records from start and reset
the cursor back to it's previous position.
@ -1111,7 +1111,7 @@ def fetch_all_from_start(trans_id):
# Reset the cursor to start to fetch all the records.
conn.reset_cursor_at(0)
status, result = conn.async_fetchmany_2darray(-1)
status, result = conn.async_fetchmany_2darray(limit)
if not status:
status = 'Error'
else:

View File

@ -69,6 +69,7 @@ function GenerateGraph({graphType, graphData, ...props}) {
let showDataPoints = queryToolCtx.preferences.graphs['graph_data_points'];
let useDiffPointStyle = queryToolCtx.preferences.graphs['use_diff_point_style'];
let showToolTip = queryToolCtx.preferences.graphs['graph_mouse_track'];
let lineBorderWidth = queryToolCtx.preferences.graphs['graph_line_border_width'];
// Below options are used by chartjs while rendering the graph
const options = useMemo(()=>({
@ -76,6 +77,9 @@ function GenerateGraph({graphType, graphData, ...props}) {
point: {
radius: showDataPoints ? DATA_POINT_SIZE : 0,
},
line: {
borderWidth: lineBorderWidth,
},
},
plugins: {
legend: {
@ -100,7 +104,7 @@ function GenerateGraph({graphType, graphData, ...props}) {
borderWidth: 1,
backgroundColor: 'rgba(54, 162, 235, 0.3)'
},
mode: 'xy',
mode: 'x',
},
}
},
@ -249,12 +253,16 @@ export function GraphVisualiser({initColumns}) {
const onGenerate = async ()=>{
setLoaderText(gettext('Fetching all the records...'));
onResetZoom();
let url = url_for('sqleditor.fetch_all_from_start', {
'trans_id': queryToolCtx.params.trans_id
'trans_id': queryToolCtx.params.trans_id,
'limit': queryToolCtx.preferences.sqleditor.row_limit
});
let res = await queryToolCtx.api.get(url);
setLoaderText(gettext('Rendering data points...'));
// Set the Graph Data
setGraphData(
getGraphDataSet(res.data.data.result, columns, xaxis, yaxis, queryToolCtx)
@ -265,7 +273,7 @@ export function GraphVisualiser({initColumns}) {
// Reset the zoom to normal
const onResetZoom = ()=> {
chartObjRef.current.resetZoom();
chartObjRef?.current?.resetZoom();
};
// Download button callback

View File

@ -12,7 +12,7 @@ from flask_babel import gettext
from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\
PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_EXPLAIN, PREF_LABEL_OPTIONS,\
PREF_LABEL_EDITOR, PREF_LABEL_CSV_TXT, PREF_LABEL_RESULTS_GRID,\
PREF_LABEL_SQL_FORMATTING
PREF_LABEL_SQL_FORMATTING, PREF_LABEL_GRAPH_VISUALISER
from pgadmin.utils import SHORTCUT_FIELDS as shortcut_fields, \
ACCESSKEY_FIELDS as accesskey_fields
@ -806,3 +806,13 @@ def register_query_tool_preferences(self):
'when the tab key or auto-indent are used.'
)
)
self.row_limit = self.preference.register(
'graph_visualiser', 'row_limit',
gettext("Row Limit"), 'integer',
10000, min_val=1, category_label=PREF_LABEL_GRAPH_VISUALISER,
help_str=gettext('This setting specifies the maximum number of rows '
'that will be plotted on a chart. Increasing this '
'limit may impact performance if charts are plotted '
'with very high numbers of rows.')
)

View File

@ -26,6 +26,7 @@ PREF_LABEL_RESULTS_GRID = gettext('Results grid')
PREF_LABEL_SQL_FORMATTING = gettext('SQL formatting')
PREF_LABEL_TABS_SETTINGS = gettext('Tab settings')
PREF_LABEL_REFRESH_RATES = gettext('Refresh rates')
PREF_LABEL_GRAPH_VISUALISER = gettext('Graph Visualiser')
PGADMIN_STRING_SEPARATOR = '_$PGADMIN$_'
PGADMIN_NODE = 'pgadmin.node.%s'

View File

@ -109,6 +109,7 @@ describe('Graphs.js', ()=>{
show_graphs: true,
graph_data_points: true,
graph_mouse_track: true,
graph_line_border_width: 2
};
graphComp = mount(<Graphs preferences={dashboardPref} sid={sid} did={did} enablePoll={false} pageVisible={true} />);
@ -137,6 +138,7 @@ describe('Graphs.js', ()=>{
show_graphs: true,
graph_data_points: true,
graph_mouse_track: true,
graph_line_border_width: 2
};
graphComp.setProps({preferences: dashboardPref});
let found = graphComp.find('[data-testid="graph-poll-delay"]');

View File

@ -34,6 +34,7 @@ describe('<GraphsWrapper /> component', ()=>{
errorMsg={null}
showTooltip={true}
showDataPoints={true}
lineBorderWidth={2}
isDatabase={false} />);
});
@ -87,4 +88,4 @@ describe('<GraphsWrapper /> component', ()=>{
expect(found.at(4)).toIncludeText('Some error occurred');
done();
});
});
});