2025, Oct 20 23:31
NiceGUI में AG Grid की सेल-चेंज फ्लैशिंग को भरोसेमंद कैसे बनाएं
AG Grid में सेल-चेंज फ्लैशिंग NiceGUI व Pandas के साथ क्यों नहीं दिखती, और getRowId, enableCellChangeFlash व setDataValue से बिना पूर्ण रिफ्रेश इसे भरोसेमंद कैसे बनाएं.
AG Grid में सेल अपडेट्स की फ्लैशिंग UX का छोटा पर उपयोगी पहलू है: जैसे ही मान बदलते हैं, नजर स्वाभाविक रूप से उसी पर जाती है जो अलग दिखता है। लेकिन NiceGUI में Pandas DataFrame बैकएंड के साथ AG Grid जोड़ते समय, सभी सही विकल्प सेट करना आसान है और फिर भी एनीमेशन का ट्रिगर कभी दिखता ही नहीं। असली अड़चन ग्रिड के रिफ्रेश होने के तरीके में है।
समस्या को पुनः उत्पन्न करना
निम्न उदाहरण Name और Score वाली ग्रिड रेंडर करता है, सेल-चेंज फ्लैशिंग चालू करता है, और डेटा बदलने के बाद बदले हुए सेल्स को प्रोग्रामेटिक रूप से हाइलाइट करने की कोशिश करता है। बेहतर दृश्यता के लिए यह डिफॉल्ट हरे रंग को लाल से भी ओवरराइड करता है।
from nicegui import ui
import pandas as pd, random
# A) HighlightChangesModule रजिस्टर करें
ui.add_head_html('''
<script>
  const { ModuleRegistry, HighlightChangesModule } = window.agGrid;
  ModuleRegistry.registerModules([ HighlightChangesModule ]);
</script>
''')
# B) Alpine थीम में फ्लैश रंग लाल करें
ui.add_head_html('''
<style>
  .ag-theme-alpine .ag-cell-data-changed {
    background-color: red !important;
    color: white !important;
    transition: background-color 0.5s ease;
  }
</style>
''')
# C) नमूना डेटा
dataset = pd.DataFrame({'id':[0,1,2], 'name': ['Alice','Bob','Charlie'], 'score': [10,20,30]})
prior = dataset.copy()
# D) बदलाव-फ्लैश सक्षम ग्रिड
with ui.column().classes('w-full ag-theme-alpine'):
    table = ui.aggrid(
        {
            "columnDefs": [{"field": "id"}, {"field": "name"}, {"field": "score", 'enableCellChangeFlash': True}],
            "rowData": dataset.to_dict("records"),
            "animateRows": True,
            "cellFlashDelay": 500,
            "cellFadeDelay": 1000,
            'deltaRowDataMode': True,
            # ':getRowId': 'params => params.data.id',
        }
    )
# E) स्कोर अपडेट करें: डेटा दोबारा लिखें, ग्रिड रिफ्रेश करें, फिर सेल्स को फ्लैश कराने की कोशिश करें
def bump_scores():
    global dataset, prior
    prior = dataset.copy()
    dataset['score'] = [random.randint(0,100) for _ in dataset.index]
    table.options['rowData'] = dataset.to_dict('records')
    table.update()
    changed_cells = []
    for i in dataset.index:
        if dataset.at[i,'score'] != prior.at[i,'score']:
            changed_cells.append({'rowIndex': i, 'column': 'score'})
    table.run_method('api.flashCells', {'cells': changed_cells})
ui.button('Update Scores', on_click=bump_scores)
ui.run(host="127.0.0.1")
असल में क्या बिगड़ रहा है
दोषी ग्रिड का रिफ्रेश है। जब पूरी ग्रिड दोबारा रेंडर होती है, तो वह आंतरिक “अभी-अभी मान बदला” वाली स्थिति, जिसे AG Grid अस्थायी हाइलाइट क्लास लगाने के लिए उपयोग करता है, नए DOM पर मौजूद नहीं रहती। दूसरे शब्दों में, table.update() पूर्ण री-ड्रॉ को ट्रिगर करता है, इसलिए ग्रिड किसी दिए गए सेल के पुराने और नए मान को नहीं पहचान पाता और फ्लैशिंग क्लास लागू नहीं होती।
अलग से, अगर डिबग करते समय आप किसी टूटे हुए डॉक्यूमेंटेशन URL के पीछे भागे, तो उससे भी मदद नहीं मिलेगी। और अगर फिर भी कुछ काम नहीं कर रहा, तो ब्राउज़र के DevTools Console में जाकर JavaScript त्रुटियों की जाँच करना एक व्यावहारिक जाँच है।
वह उपाय जो फ्लैशिंग को भरोसेमंद बनाता है
ग्रिड को फिर से रेंडर करने के बजाय, सेल मानों को वहीं पर अपडेट करें। getRowId के जरिए AG Grid को स्थिर पंक्ति पहचान दीजिए, enableCellChangeFlash सक्षम करें, और बदले हुए सेल मान सेट करने के लिए grid API का उपयोग करें। इससे AG Grid डेल्टा पहचानता है और अपना बिल्ट-इन एनीमेशन लागू करता है। फ्लैश को लाल और टेक्स्ट को सफेद रखने के लिए रंगों को CSS वेरिएबल्स से अनुकूलित किया जा सकता है।
from nicegui import ui
import pandas as pd
import random
records = pd.DataFrame({
    'id': [0, 1, 2],
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [10, 20, 30],
})
ui.add_head_html('''
<style>
  :root {
    --ag-value-change-value-highlight-bg-color: red;
    --ag-value-change-value-highlight-color: white;
  }
  .ag-theme-alpine .ag-cell-data-changed,
  .ag-cell-data-changed-animation {
    background-color: var(--ag-value-change-value-highlight-bg-color) !important;
    color: var(--ag-value-change-value-highlight-color) !important;
  }
</style>
''')
with ui.column().classes('w-full ag-theme-alpine'):
    sheet = ui.aggrid.from_pandas(records, options={
        'columnDefs': [
            {'headerName': col.capitalize(), 'field': col}
            for col in records.columns
        ],
        'cellFlashDuration': 800,
        'cellFadeDuration': 1500,
        'defaultColDef': {'enableCellChangeFlash': True},
        ':getRowId': 'params => params.data.id.toString()',
    })
def apply_new_scores():
    for _, rec in records.iterrows():
        nid = rec['id']
        new_val = random.randint(0, 100)
        records.loc[records['id'] == nid, 'score'] = new_val
        sheet.run_row_method(str(nid), 'setDataValue', 'score', new_val)
ui.button('Update Scores', on_click=apply_new_scores)
ui.run(host='127.0.0.1')
यह क्यों मायने रखता है
जब आप ग्रिड इंस्टेंस को जस का तस रखते हैं और केवल बदले हुए मान पैच करते हैं, तो AG Grid वही कर पाता है जिसके लिए वह बना है: फर्क पहचानना और उसे एनीमेट करना। इससे कंपोनेंट लाइफसाइकल से जूझने की जरूरत नहीं पड़ती और पूर्ण री-ड्रॉ के बाद हाथ से बदले हुए सेल ढूंढकर फ्लैश की नकल करने की आवश्यकता भी खत्म होती है।
मुख्य बातें
अगर सेल-चेंज एनीमेशन चाहिए, तो पूरी ग्रिड को रिफ्रेश न करें। पंक्ति IDs स्थिर रखें, बिल्ट-इन फ्लैशिंग सक्षम करें, और NiceGUI ब्रिज के जरिए setDataValue कॉल करें ताकि AG Grid प्रति-सेल बदलाव ट्रैक कर सके। अगर अन्य समस्याओं का संदेह हो, तो तुरंत जाँच लें कि जिस डॉक्यूमेंटेशन लिंक का उपयोग कर रहे हैं वह सही है, और ब्राउज़र कंसोल में त्रुटियाँ देखें। इन समायोजनों के साथ, Score कॉलम भरोसेमंद तरीके से फ्लैश होता है और UX का ध्यान उसी पर रहता है जो बदला है।
यह लेख StackOverflow पर प्रश्न (लेखक: Iain MacCormick) और Detlef के उत्तर पर आधारित है।