refactor(sql_explorer): Replace Plotly with SVG rendering for plots
Replaces the Plotly-based graph generation in the SQL Explorer with direct SVG rendering within an HTML template, similar to the exercise progress sparklines. - Modifies `routes/sql_explorer.py` endpoints (`plot_query`, `plot_unsaved_query`) to fetch raw data instead of using pandas/Plotly. - Adds `utils.prepare_svg_plot_data` to process raw SQL results, determine plot type (scatter, line, bar, table), normalize data, and prepare it for SVG. - Creates `templates/partials/sql_explorer/svg_plot.html` to render the SVG plot with axes, ticks, labels, and basic tooltips. - Removes the `generate_plot` function's usage for SQL Explorer and the direct dependency on Plotly for this feature.
This commit is contained in:
@@ -5,7 +5,7 @@ from flask import Blueprint, render_template, request, current_app, jsonify
|
||||
from jinja2_fragments import render_block
|
||||
from flask_htmx import HTMX
|
||||
from extensions import db
|
||||
from utils import generate_plot
|
||||
from utils import prepare_svg_plot_data # Will be created for SVG data prep
|
||||
|
||||
sql_explorer_bp = Blueprint('sql_explorer', __name__, url_prefix='/sql')
|
||||
htmx = HTMX()
|
||||
@@ -281,17 +281,47 @@ def sql_schema():
|
||||
def plot_query(query_id):
|
||||
(title, query) = _get_saved_query(query_id)
|
||||
if not query: return "Query not found", 404
|
||||
results_df = db.read_sql_as_df(query)
|
||||
plot_div = generate_plot(results_df, title)
|
||||
return plot_div
|
||||
# Fetch raw results instead of DataFrame
|
||||
(results, columns, error) = _execute_sql(query)
|
||||
if error:
|
||||
# Return an HTML snippet indicating the error
|
||||
return f'<div class="p-4 text-red-700 bg-red-100 border border-red-400 rounded">Error executing query: {error}</div>', 400
|
||||
if not results:
|
||||
# Return an HTML snippet indicating no data
|
||||
return '<div class="p-4 text-yellow-700 bg-yellow-100 border border-yellow-400 rounded">No data returned by query.</div>'
|
||||
|
||||
try:
|
||||
# Prepare data for SVG plotting (function to be created in utils.py)
|
||||
plot_data = prepare_svg_plot_data(results, columns, title)
|
||||
# Render the new SVG template
|
||||
return render_template('partials/sql_explorer/svg_plot.html', **plot_data)
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Error preparing SVG plot data: {e}")
|
||||
# Return an HTML snippet indicating a processing error
|
||||
return f'<div class="p-4 text-red-700 bg-red-100 border border-red-400 rounded">Error preparing plot data: {e}</div>', 500
|
||||
|
||||
@sql_explorer_bp.route("/plot/show", methods=['POST'])
|
||||
def plot_unsaved_query():
|
||||
query = request.form.get('query')
|
||||
title = request.form.get('title')
|
||||
results_df = db.read_sql_as_df(query)
|
||||
plot_div = generate_plot(results_df, title)
|
||||
return plot_div
|
||||
title = request.form.get('title', 'SQL Query Plot') # Add default title
|
||||
# Fetch raw results instead of DataFrame
|
||||
(results, columns, error) = _execute_sql(query)
|
||||
if error:
|
||||
# Return an HTML snippet indicating the error
|
||||
return f'<div class="p-4 text-red-700 bg-red-100 border border-red-400 rounded">Error executing query: {error}</div>', 400
|
||||
if not results:
|
||||
# Return an HTML snippet indicating no data
|
||||
return '<div class="p-4 text-yellow-700 bg-yellow-100 border border-yellow-400 rounded">No data returned by query.</div>'
|
||||
|
||||
try:
|
||||
# Prepare data for SVG plotting (function to be created in utils.py)
|
||||
plot_data = prepare_svg_plot_data(results, columns, title)
|
||||
# Render the new SVG template
|
||||
return render_template('partials/sql_explorer/svg_plot.html', **plot_data)
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Error preparing SVG plot data: {e}")
|
||||
# Return an HTML snippet indicating a processing error
|
||||
return f'<div class="p-4 text-red-700 bg-red-100 border border-red-400 rounded">Error preparing plot data: {e}</div>', 500
|
||||
|
||||
@sql_explorer_bp.route("/generate_sql", methods=['POST'])
|
||||
def generate_sql():
|
||||
|
||||
Reference in New Issue
Block a user