pentarosarium commited on
Commit
a1bce75
·
1 Parent(s): 480a85a

3.71 fix viz

Browse files
Files changed (1) hide show
  1. app.py +142 -71
app.py CHANGED
@@ -548,26 +548,38 @@ class ProcessingUI:
548
 
549
  def setup_events_tab(self):
550
  """Setup the events timeline display"""
551
- # Event type filter
552
- self.event_filter = st.multiselect(
 
 
 
553
  "Тип события:",
554
  options=["Отчетность", "РЦБ", "Суд"],
555
- default=None
 
556
  )
557
 
558
  # Timeline container
559
- self.timeline_container = st.container()
 
560
 
561
  def setup_analytics_tab(self):
562
  """Setup the analytics display"""
563
- # Processing speed chart
564
- self.speed_chart = st.empty()
565
-
566
- # Sentiment distribution pie chart
567
- self.sentiment_chart = st.empty()
568
-
569
- # Entity correlation matrix
570
- self.correlation_chart = st.empty()
 
 
 
 
 
 
 
571
 
572
  def update_stats(self, row, sentiment, event_type, processing_speed):
573
  """Update all statistics and displays"""
@@ -616,27 +628,45 @@ class ProcessingUI:
616
 
617
  def _update_recent_items(self, row, sentiment, event_type):
618
  """Update recent items display with custom styling"""
619
- items_html = "<div style='max-height: 300px; overflow-y: auto;'>"
620
-
621
- # Add new item to the beginning of the list
622
- item_class = 'recent-item '
623
- if sentiment == 'Negative':
624
- item_class += 'negative-item'
625
- elif sentiment == 'Positive':
626
- item_class += 'positive-item'
627
- if event_type != 'Нет':
628
- item_class += ' event-item'
629
 
630
- items_html += f"""
631
- <div class='{item_class}'>
632
- <strong>{row['Объект']}</strong><br>
633
- {row['Заголовок']}<br>
634
- <small>
635
- Тональность: {sentiment}
636
- {f" | Событие: {event_type}" if event_type != 'Нет' else ""}
637
- </small>
638
- </div>
639
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
 
641
  items_html += "</div>"
642
  self.recent_items_container.markdown(items_html, unsafe_allow_html=True)
@@ -647,60 +677,101 @@ class ProcessingUI:
647
  if not stats:
648
  return
649
 
650
- # Update entity filter options
651
- current_options = set(self.entity_filter)
652
- all_entities = set(stats.keys())
653
- if current_options != all_entities:
654
- self.entity_filter = list(all_entities)
655
-
656
  # Create entity comparison chart using Plotly
657
  df_entities = pd.DataFrame.from_dict(stats, orient='index')
 
 
658
  fig = go.Figure(data=[
659
- go.Bar(name='Total', x=df_entities.index, y=df_entities['total']),
660
- go.Bar(name='Negative', x=df_entities.index, y=df_entities['negative']),
661
- go.Bar(name='Events', x=df_entities.index, y=df_entities['events'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  ])
663
- fig.update_layout(barmode='group', title='Entity Statistics')
664
- self.entity_chart.plotly_chart(fig, use_container_width=True)
665
 
666
- def _update_events_view(self, row, event_type):
667
- """Update events timeline"""
668
- if event_type != 'Нет':
669
- event_html = f"""
670
- <div class='timeline-item'>
671
- <div class='timeline-marker'></div>
672
- <div class='timeline-content'>
673
- <h3>{event_type}</h3>
674
- <p><strong>{row['Объект']}</strong></p>
675
- <p>{row['Заголовок']}</p>
676
- <small>{datetime.now().strftime('%H:%M:%S')}</small>
677
- </div>
678
- </div>
679
- """
680
- with self.timeline_container:
681
- st.markdown(event_html, unsafe_allow_html=True)
682
 
683
  def _update_analytics(self):
684
  """Update analytics tab visualizations"""
685
  stats = st.session_state.processing_stats
686
 
687
- # Processing speed chart
688
- speeds = stats['processing_speed'][-1:] # Last 1 measurement
689
- fig_speed = go.Figure(data=go.Scatter(y=speeds, mode='lines'))
690
- fig_speed.update_layout(title='Processing Speed Over Time')
691
- self.speed_chart.plotly_chart(fig_speed, use_container_width=True)
692
-
693
- # Add other analytics visualizations as needed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
 
695
  def update_progress(self, current, total):
696
- """Update progress bar and elapsed time"""
697
  progress = current / total
698
  self.progress_bar.progress(progress)
699
  self.status.text(f"Обрабатываем {current} из {total} сообщений...")
700
 
701
- # Update elapsed time
702
- elapsed = time.time() - st.session_state.processing_stats['start_time']
703
- self.timer_display.markdown(f"⏱️ {format_elapsed_time(elapsed)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
704
 
705
 
706
  class EventDetectionSystem:
@@ -1477,7 +1548,7 @@ def main():
1477
  st.set_page_config(layout="wide")
1478
 
1479
  with st.sidebar:
1480
- st.title("::: AI-анализ мониторинга новостей (v.3.70):::")
1481
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1482
 
1483
  model_choice = st.radio(
 
548
 
549
  def setup_events_tab(self):
550
  """Setup the events timeline display"""
551
+ # Event type filter - store in session state
552
+ if 'event_filter' not in st.session_state:
553
+ st.session_state.event_filter = []
554
+
555
+ st.session_state.event_filter = st.multiselect(
556
  "Тип события:",
557
  options=["Отчетность", "РЦБ", "Суд"],
558
+ default=None,
559
+ key="event_filter_key"
560
  )
561
 
562
  # Timeline container
563
+ if 'timeline_container' not in st.session_state:
564
+ st.session_state.timeline_container = st.container()
565
 
566
  def setup_analytics_tab(self):
567
  """Setup the analytics display"""
568
+ # Create containers for analytics
569
+ self.speed_container = st.container()
570
+ with self.speed_container:
571
+ st.subheader("Скорость обработки")
572
+ self.speed_chart = st.empty()
573
+
574
+ self.sentiment_container = st.container()
575
+ with self.sentiment_container:
576
+ st.subheader("Распределение тональности")
577
+ self.sentiment_chart = st.empty()
578
+
579
+ self.correlation_container = st.container()
580
+ with self.correlation_container:
581
+ st.subheader("Корреляция между метриками")
582
+ self.correlation_chart = st.empty()
583
 
584
  def update_stats(self, row, sentiment, event_type, processing_speed):
585
  """Update all statistics and displays"""
 
628
 
629
  def _update_recent_items(self, row, sentiment, event_type):
630
  """Update recent items display with custom styling"""
631
+ # Maintain a list of recent items in session state
632
+ if 'recent_items' not in st.session_state:
633
+ st.session_state.recent_items = []
 
 
 
 
 
 
 
634
 
635
+ # Add new item to the beginning of the list
636
+ new_item = {
637
+ 'entity': row['Объект'],
638
+ 'headline': row['Заголовок'],
639
+ 'sentiment': sentiment,
640
+ 'event_type': event_type,
641
+ 'time': datetime.now().strftime('%H:%M:%S')
642
+ }
643
+
644
+ st.session_state.recent_items.insert(0, new_item)
645
+ # Keep only last 10 items
646
+ st.session_state.recent_items = st.session_state.recent_items[:10]
647
+
648
+ # Create HTML for all recent items
649
+ items_html = "<div style='max-height: 400px; overflow-y: auto;'>"
650
+
651
+ for item in st.session_state.recent_items:
652
+ if item['sentiment'] in ['Positive', 'Negative']: # Only show Positive and Negative items
653
+ item_class = 'recent-item '
654
+ if item['sentiment'] == 'Negative':
655
+ item_class += 'negative-item'
656
+ elif item['sentiment'] == 'Positive':
657
+ item_class += 'positive-item'
658
+
659
+ items_html += f"""
660
+ <div class='{item_class}'>
661
+ <strong>{item['entity']}</strong><br>
662
+ {item['headline']}<br>
663
+ <small>
664
+ Тональность: {item['sentiment']}
665
+ {f" | Событие: {item['event_type']}" if item['event_type'] != 'Нет' else ""}
666
+ | {item['time']}
667
+ </small>
668
+ </div>
669
+ """
670
 
671
  items_html += "</div>"
672
  self.recent_items_container.markdown(items_html, unsafe_allow_html=True)
 
677
  if not stats:
678
  return
679
 
680
+ # Get filtered entities
681
+ filtered_entities = self.entity_filter or stats.keys()
682
+
 
 
 
683
  # Create entity comparison chart using Plotly
684
  df_entities = pd.DataFrame.from_dict(stats, orient='index')
685
+ df_entities = df_entities.loc[filtered_entities] # Apply filter
686
+
687
  fig = go.Figure(data=[
688
+ go.Bar(
689
+ name='Всего',
690
+ x=df_entities.index,
691
+ y=df_entities['total'],
692
+ marker_color='#E0E0E0' # Light gray
693
+ ),
694
+ go.Bar(
695
+ name='Негативные',
696
+ x=df_entities.index,
697
+ y=df_entities['negative'],
698
+ marker_color='#FF6B6B' # Red
699
+ ),
700
+ go.Bar(
701
+ name='События',
702
+ x=df_entities.index,
703
+ y=df_entities['events'],
704
+ marker_color='#2196F3' # Blue
705
+ )
706
  ])
 
 
707
 
708
+ fig.update_layout(
709
+ barmode='group',
710
+ title='Статистика по организациям',
711
+ xaxis_title='Организация',
712
+ yaxis_title='Количество',
713
+ showlegend=True
714
+ )
715
+
716
+ self.entity_chart.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
717
 
718
  def _update_analytics(self):
719
  """Update analytics tab visualizations"""
720
  stats = st.session_state.processing_stats
721
 
722
+ # Processing speed chart - showing last 20 measurements
723
+ speeds = stats['processing_speed'][-20:]
724
+ if speeds:
725
+ fig_speed = go.Figure(data=go.Scatter(
726
+ y=speeds,
727
+ mode='lines+markers',
728
+ name='Скорость',
729
+ line=dict(color='#4CAF50')
730
+ ))
731
+ fig_speed.update_layout(
732
+ title='Скорость обработки',
733
+ yaxis_title='Сообщений в секунду',
734
+ showlegend=True
735
+ )
736
+ self.speed_chart.plotly_chart(fig_speed, use_container_width=True)
737
+
738
+ # Sentiment distribution pie chart
739
+ if stats['entities']:
740
+ total_negative = sum(e['negative'] for e in stats['entities'].values())
741
+ total_positive = sum(e['events'] for e in stats['entities'].values())
742
+ total_neutral = sum(e['total'] for e in stats['entities'].values()) - total_negative - total_positive
743
+
744
+ fig_sentiment = go.Figure(data=[go.Pie(
745
+ labels=['Негативные', 'Позитивные', 'Нейтральные'],
746
+ values=[total_negative, total_positive, total_neutral],
747
+ marker_colors=['#FF6B6B', '#4ECDC4', '#95A5A6']
748
+ )])
749
+ self.sentiment_chart.plotly_chart(fig_sentiment, use_container_width=True)
750
 
751
  def update_progress(self, current, total):
752
+ """Update progress bar, elapsed time and estimated time remaining"""
753
  progress = current / total
754
  self.progress_bar.progress(progress)
755
  self.status.text(f"Обрабатываем {current} из {total} сообщений...")
756
 
757
+ # Calculate times
758
+ current_time = time.time()
759
+ elapsed = current_time - st.session_state.processing_stats['start_time']
760
+
761
+ # Calculate processing speed and estimated time remaining
762
+ if current > 0:
763
+ speed = current / elapsed # items per second
764
+ remaining_items = total - current
765
+ estimated_remaining = remaining_items / speed if speed > 0 else 0
766
+
767
+ time_display = (
768
+ f"⏱️ Прошло: {format_elapsed_time(elapsed)} | "
769
+ f"Осталось: {format_elapsed_time(estimated_remaining)}"
770
+ )
771
+ else:
772
+ time_display = f"⏱️ Прошло: {format_elapsed_time(elapsed)}"
773
+
774
+ self.timer_display.markdown(time_display)
775
 
776
 
777
  class EventDetectionSystem:
 
1548
  st.set_page_config(layout="wide")
1549
 
1550
  with st.sidebar:
1551
+ st.title("::: AI-анализ мониторинга новостей (v.3.71+):::")
1552
  st.subheader("по материалам СКАН-ИНТЕРФАКС")
1553
 
1554
  model_choice = st.radio(