diff --git a/src/graph_notebook/magics/graph_magic.py b/src/graph_notebook/magics/graph_magic.py index 2144df72..0f77a853 100644 --- a/src/graph_notebook/magics/graph_magic.py +++ b/src/graph_notebook/magics/graph_magic.py @@ -132,6 +132,15 @@ def query_type_to_action(query_type): return 'sparqlupdate' +def results_per_page_check(results_per_page): + if results_per_page < 1: + return 1 + elif results_per_page > 1000: + return 1000 + else: + return int(results_per_page) + + # TODO: refactor large magic commands into their own modules like what we do with %neptune_ml # noinspection PyTypeChecker @magics_class @@ -271,6 +280,8 @@ def sparql(self, line='', cell='', local_ns: dict = None): parser.add_argument('-sd', '--simulation-duration', type=int, default=1500, help='Specifies maximum duration of visualization physics simulation. Default is 1500ms') parser.add_argument('--silent', action='store_true', default=False, help="Display no query output.") + parser.add_argument('-r', '--results-per-page', type=int, default=10, + help='Specifies how many query results to display per page in the output. Default is 10') parser.add_argument('--no-scroll', action='store_true', default=False, help="Display the entire output without a scroll bar.") args = parser.parse_args(line.split()) @@ -357,8 +368,10 @@ def sparql(self, line='', cell='', local_ns: dict = None): rows_and_columns = sparql_get_rows_and_columns(results) if rows_and_columns is not None: table_id = f"table-{str(uuid.uuid4())[:8]}" + visible_results = results_per_page_check(args.results_per_page) first_tab_html = sparql_table_template.render(columns=rows_and_columns['columns'], - rows=rows_and_columns['rows'], guid=table_id) + rows=rows_and_columns['rows'], guid=table_id, + amount=visible_results) # Handling CONSTRUCT and DESCRIBE on their own because we want to maintain the previous result # pattern of showing a tsv with each line being a result binding in addition to new ones. @@ -478,6 +491,8 @@ def gremlin(self, line, cell, local_ns: dict = None): parser.add_argument('-sd', '--simulation-duration', type=int, default=1500, help='Specifies maximum duration of visualization physics simulation. Default is 1500ms') parser.add_argument('--silent', action='store_true', default=False, help="Display no query output.") + parser.add_argument('-r', '--results-per-page', type=int, default=10, + help='Specifies how many query results to display per page in the output. Default is 10') parser.add_argument('--no-scroll', action='store_true', default=False, help="Display the entire output without a scroll bar.") @@ -573,7 +588,9 @@ def gremlin(self, line, cell, local_ns: dict = None): f'unable to create gremlin network from result. Skipping from result set: {value_error}') table_id = f"table-{str(uuid.uuid4()).replace('-', '')[:8]}" - first_tab_html = gremlin_table_template.render(guid=table_id, results=query_res) + visible_results = results_per_page_check(args.results_per_page) + first_tab_html = gremlin_table_template.render(guid=table_id, results=query_res, + amount=visible_results) if not args.silent: metadata_output = widgets.Output(layout=gremlin_layout) @@ -1619,6 +1636,8 @@ def handle_opencypher_query(self, line, cell, local_ns): parser.add_argument('-sd', '--simulation-duration', type=int, default=1500, help='Specifies maximum duration of visualization physics simulation. Default is 1500ms') parser.add_argument('--silent', action='store_true', default=False, help="Display no query output.") + parser.add_argument('-r', '--results-per-page', type=int, default=10, + help='Specifies how many query results to display per page in the output. Default is 10') parser.add_argument('--no-scroll', action='store_true', default=False, help="Display the entire output without a scroll bar.") args = parser.parse_args(line.split()) @@ -1681,8 +1700,10 @@ def handle_opencypher_query(self, line, cell, local_ns): titles.append('Console') if rows_and_columns is not None: table_id = f"table-{str(uuid.uuid4())[:8]}" + visible_results = results_per_page_check(args.results_per_page) table_html = opencypher_table_template.render(columns=rows_and_columns['columns'], - rows=rows_and_columns['rows'], guid=table_id) + rows=rows_and_columns['rows'], guid=table_id, + amount=visible_results) # Display Graph Tab (if exists) if force_graph_output: diff --git a/src/graph_notebook/visualization/templates/gremlin_table.html b/src/graph_notebook/visualization/templates/gremlin_table.html index 877491cc..20dda4b9 100644 --- a/src/graph_notebook/visualization/templates/gremlin_table.html +++ b/src/graph_notebook/visualization/templates/gremlin_table.html @@ -34,13 +34,23 @@ </table> <script type="text/javascript"> require(["datatables"], function (datatables) { + function sort_remove_dup_ary(ary) { + return ary.sort(function(a, b){return a-b}).filter(function(item, pos, ary) { return !pos || item != ary[pos - 1] }) + } + + var paginationAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, -1]); + var optionsAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, "All"]); + var dt = $('#{{guid}}').DataTable({ scrollY: true, scrollX: true, + //scrollCollapse: true, columnDefs: [ {targets: [0], width: "5%"}, {targets: [1], minWidth: "95%"} - ] + ], + "lengthMenu": [paginationAry, optionsAry], + "pageLength": {{amount}} }); var wrapper = $('#{{guid}}_wrapper'); diff --git a/src/graph_notebook/visualization/templates/opencypher_table.html b/src/graph_notebook/visualization/templates/opencypher_table.html index 3e1f3934..4b80a8ae 100644 --- a/src/graph_notebook/visualization/templates/opencypher_table.html +++ b/src/graph_notebook/visualization/templates/opencypher_table.html @@ -41,13 +41,22 @@ </table> <script type="text/javascript"> require(["datatables"], function (datatables) { + function sort_remove_dup_ary(ary) { + return ary.sort(function(a, b){return a-b}).filter(function(item, pos, ary) { return !pos || item != ary[pos - 1] }) + } + + var paginationAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, -1]); + var optionsAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, "All"]); + $('#{{guid}}').DataTable({ scrollY: true, scrollX: true, columnDefs: [ {targets: [0], width: "5%"}, ], - bAutoWidth: true + bAutoWidth: true, + "lengthMenu": [paginationAry, optionsAry], + "pageLength": {{amount}} }); }) </script> diff --git a/src/graph_notebook/visualization/templates/sparql_table.html b/src/graph_notebook/visualization/templates/sparql_table.html index 3e1f3934..4b80a8ae 100644 --- a/src/graph_notebook/visualization/templates/sparql_table.html +++ b/src/graph_notebook/visualization/templates/sparql_table.html @@ -41,13 +41,22 @@ </table> <script type="text/javascript"> require(["datatables"], function (datatables) { + function sort_remove_dup_ary(ary) { + return ary.sort(function(a, b){return a-b}).filter(function(item, pos, ary) { return !pos || item != ary[pos - 1] }) + } + + var paginationAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, -1]); + var optionsAry = sort_remove_dup_ary([{{amount}}, 10, 25, 50, 100, "All"]); + $('#{{guid}}').DataTable({ scrollY: true, scrollX: true, columnDefs: [ {targets: [0], width: "5%"}, ], - bAutoWidth: true + bAutoWidth: true, + "lengthMenu": [paginationAry, optionsAry], + "pageLength": {{amount}} }); }) </script>