plotguy 2.2.4__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.2.4
3
+ Version: 2.3.0
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -1,5 +1,6 @@
1
1
  import warnings
2
2
  warnings.simplefilter("ignore", UserWarning)
3
+ #warnings.simplefilter("ignore", RuntimeWarning)
3
4
 
4
5
  import datetime
5
6
  import os
@@ -12,6 +13,7 @@ import requests
12
13
  import pandas as pd
13
14
  import numpy as np
14
15
  import io
16
+ import re
15
17
 
16
18
  from .equity_curves import *
17
19
  from .signals import *
@@ -135,6 +137,8 @@ def save_backtest_result(df, para_combination_item):
135
137
  ### for intraday ###
136
138
  if intraday:
137
139
  df_daily = df.resample('D').agg({'price': agg_price})
140
+ #df_daily = df.resample('D').agg({'price': agg_price, 'equity_value': agg_price})
141
+ df_daily = df_daily[df_daily['price'].notna()]
138
142
  else:
139
143
  df_daily = df
140
144
 
@@ -196,6 +200,7 @@ def save_backtest_result(df, para_combination_item):
196
200
  yearly_stats_string += f'{year},year_trade_count:0.00,year_win_rate:00.00,year_return:-00.00|'
197
201
 
198
202
  yearly_stats_string = yearly_stats_string[:-1]
203
+ correlation = 0
199
204
 
200
205
  elif len(df_count) > 0:
201
206
 
@@ -277,8 +282,11 @@ def save_backtest_result(df, para_combination_item):
277
282
  equity_net_profit = df.at[df.index[-1], 'equity_value'] - df.at[df.index[0], 'equity_value']
278
283
 
279
284
  equity_return_on_capital = equity_net_profit / df.at[df.index[0], 'equity_value']
280
- equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (
281
- 365 / holding_period_day) - 1
285
+ if 1 + equity_return_on_capital > 0:
286
+ equity_annualized_return = (np.sign(1 + equity_return_on_capital) * np.abs(1 + equity_return_on_capital)) ** (365 / holding_period_day) - 1
287
+ else:
288
+ equity_annualized_return = -1
289
+
282
290
  equity_annualized_std = equity_pct_series.std() * math.sqrt(365)
283
291
  equity_annualized_sr = (
284
292
  equity_annualized_return - risk_free_rate / 100) / equity_annualized_std if equity_annualized_std != 0 else 0
@@ -290,8 +298,14 @@ def save_backtest_result(df, para_combination_item):
290
298
  equity_annualized_sr = round(equity_annualized_sr, 2)
291
299
  equity_net_profit_to_mdd = round(100 * equity_net_profit_to_mdd, 2)
292
300
 
301
+ df['equity_return'] = df['equity_value'].pct_change() * 100
302
+ df['price_return'] = df['price'].pct_change() * 100
303
+
304
+ correlation = df['equity_return'].corr(df['price_return'])
305
+
293
306
  if long_short == 'short':
294
307
  return_on_capital_diff = equity_annualized_return - (-1) * price_annualized_return
308
+ correlation *= -1
295
309
  else:
296
310
  ### consider both long and long_short ###
297
311
  return_on_capital_diff = equity_annualized_return - price_annualized_return
@@ -311,6 +325,7 @@ def save_backtest_result(df, para_combination_item):
311
325
  cov_return = round(cov_return, 2)
312
326
  cov_count = round(cov_count, 2)
313
327
  total_commission = int(round(total_commission))
328
+ correlation = round(correlation, 3)
314
329
 
315
330
  backtest_result_dict = {
316
331
  'ref_code': ref_code,
@@ -342,6 +357,7 @@ def save_backtest_result(df, para_combination_item):
342
357
  'yearly_stats_string': yearly_stats_string,
343
358
  'cov_return': cov_return,
344
359
  'cov_count': cov_count,
360
+ 'correlation': correlation,
345
361
  'total_commission': total_commission
346
362
  }
347
363
 
@@ -384,16 +400,40 @@ def get_risk_free_rate(start_date, end_date):
384
400
  # return app
385
401
 
386
402
 
387
- def plot(mode, backtest_result_df = None, number_of_curves=20):
403
+ def plot(mode, backtest_result_df = None, number_of_curves=20, filter_list= []):
388
404
 
389
405
  if mode == 'equity_curves':
390
- app = equity_curves.Plot(backtest_result_df, number_of_curves)
406
+ if len(filter_list) > 0: filter_list = convert_filter_list(filter_list)
407
+ app = equity_curves.Plot(backtest_result_df, number_of_curves, filter_list)
391
408
 
392
409
  if mode == 'aggregate':
393
410
  app = aggregate.Aggregate()
394
411
 
395
412
  return app
396
413
 
414
+ def convert_filter_list(filter_list):
415
+ '''
416
+ filter string as follows
417
+ equity_return_on_capital eg: 50% --> 50
418
+ equity_annualized_return eg: 50% --> 50
419
+ return_on_capital_diff eg: 50% --> 50
420
+ equity_annualized_sr eg: 0.9
421
+ equity_mdd_pct eg: 50% --> 50
422
+ num_of_trade eg: 10
423
+ cov_count eg: 1
424
+ cov_return eg: 1
425
+ correlation eg: 0.5
426
+ win_rate eg: 50% --> 50
427
+ '''
428
+
429
+ for i in range(len(filter_list)):
430
+ filter = filter_list[i]
431
+ pattern = r'([a-zA-Z_]+)([<>=]+)(-?\d+\.?\d*)'
432
+ match = re.match(pattern, filter)
433
+
434
+ filter_list[i] = [match.group(1), match.group(2), match.group(3)]
435
+
436
+ return filter_list
397
437
 
398
438
  def get_latest_fed_fund_rate():
399
439
  url = "https://fred.stlouisfed.org/series/FEDFUNDS"
@@ -260,7 +260,7 @@ class Aggregate:
260
260
 
261
261
  df_current = pd.DataFrame()
262
262
 
263
- df_current[f'{row['folder']}_{row['backtest_name']}_{i}'] = df['equity_value']
263
+ df_current[f'{row["folder"]}_{row["backtest_name"]}_{i}'] = df["equity_value"]
264
264
  df_current.index = df.index
265
265
  df_list.append(df_current.copy())
266
266
 
@@ -35,7 +35,6 @@ class Components:
35
35
  children=dbc.Select(id='filter_name',
36
36
  placeholder="Select Filter",
37
37
  options=[
38
- {'label': 'Exclude Stock', 'value': 'exclude'},
39
38
  {'label': 'Return on Capital >', 'value': 'equity_return_on_capital>'},
40
39
  {'label': 'Return on Capital <', 'value': 'equity_return_on_capital<'},
41
40
  {'label': 'Annualized Return >', 'value': 'equity_annualized_return>'},
@@ -52,6 +51,8 @@ class Components:
52
51
  {'label': 'COV (Count) <', 'value': 'cov_count<'},
53
52
  {'label': 'COV (Return) >', 'value': 'cov_return>'},
54
53
  {'label': 'COV (Return) <', 'value': 'cov_return<'},
54
+ {'label': 'Correlation <', 'value': 'correlation<'},
55
+ {'label': 'Correlation >', 'value': 'correlation>'},
55
56
  {'label': 'Win Rate >', 'value': 'win_rate>'},
56
57
  {'label': 'Win Rate <', 'value': 'win_rate<'},
57
58
  ],
@@ -176,79 +177,6 @@ class Components:
176
177
 
177
178
  return checkbox_div, code_list
178
179
 
179
- def update_stat_div(self, period, pct_mean, rise_mean, fall_mean):
180
- div = html.Div([
181
-
182
- dbc.Row([
183
- dbc.Col(width=2),
184
- dbc.Col(str(period[0]) + ' Days', width=2),
185
- dbc.Col(str(period[1]) + ' Days', width=2),
186
- dbc.Col(str(period[2]) + ' Days', width=2),
187
- dbc.Col(str(period[3]) + ' Days', width=2),
188
- dbc.Col(str(period[4]) + ' Days', width=2),
189
- ]),
190
-
191
- dbc.Row([
192
- dbc.Col('pct_change', width=2),
193
- dbc.Col(f'{pct_mean[0]}%', width=2),
194
- dbc.Col(f'{pct_mean[1]}%', width=2),
195
- dbc.Col(f'{pct_mean[2]}%', width=2),
196
- dbc.Col(f'{pct_mean[3]}%', width=2),
197
- dbc.Col(f'{pct_mean[4]}%', width=2),
198
- ]),
199
-
200
- dbc.Row([
201
- dbc.Col('max_rise', width=2),
202
- dbc.Col(f'{rise_mean[0]}%', width=2),
203
- dbc.Col(f'{rise_mean[1]}%', width=2),
204
- dbc.Col(f'{rise_mean[2]}%', width=2),
205
- dbc.Col(f'{rise_mean[3]}%', width=2),
206
- dbc.Col(f'{rise_mean[4]}%', width=2),
207
- ]),
208
-
209
- dbc.Row([
210
- dbc.Col('max_fall', width=2),
211
- dbc.Col(f'{fall_mean[0]}%', width=2),
212
- dbc.Col(f'{fall_mean[1]}%', width=2),
213
- dbc.Col(f'{fall_mean[2]}%', width=2),
214
- dbc.Col(f'{fall_mean[3]}%', width=2),
215
- dbc.Col(f'{fall_mean[4]}%', width=2),
216
- ]),
217
-
218
- ])
219
-
220
- return div
221
-
222
- def generate_radioitems(self, para_dict):
223
- radioitems_div = []
224
-
225
- for i, key in enumerate(para_dict):
226
- options = para_dict[key]
227
-
228
- radioitems_div.append(html.Div(key,style={'color': 'Yellow','font-size': '14px'}))
229
-
230
- radioitems_div.append(dcc.RadioItems(
231
- id={'type': 'para_radioitems', 'index': i},
232
- options=[{'label': k,
233
- 'value': k} for k in options],
234
- labelStyle={'font-size': '13px'},
235
- inputStyle={'margin-left': '10px', 'margin-right': '5px'}
236
-
237
- ), )
238
-
239
- radioitems_div.append(html.Div(html.Img(),style={'height':'10px'}))
240
-
241
- return radioitems_div
242
-
243
- def selection_title(self, para_dict, values):
244
- title = []
245
- for i, key in enumerate(para_dict):
246
- title.append(dbc.Row(
247
- [dbc.Col(key, width=6),
248
- dbc.Col(f'{values[i]}', style={'text-align': 'center'}, width=6)]))
249
-
250
- return title
251
-
252
180
  def update_performance_matrix(self, init_chart, para_keys_list, result_df, line_selected = 0):
253
181
 
254
182
  if init_chart:
@@ -258,8 +186,6 @@ class Components:
258
186
  ref_code = result_df.loc[line_selected].ref_code
259
187
 
260
188
  yearly_stats_string = result_df.loc[line_selected]['yearly_stats_string']
261
- print(result_df)
262
- print(yearly_stats_string)
263
189
 
264
190
  per_col1 =[]
265
191
  per_col2 = []
@@ -270,6 +196,7 @@ class Components:
270
196
  per_col_2_3 = [html.Div('BaH',style={'text-align': 'center', 'font-weight': 'bold', 'color':'yellow'})]
271
197
 
272
198
  keys = ['num_of_trade',
199
+ 'correlation',
273
200
  'equity_net_profit',
274
201
  'equity_net_profit_to_mdd',
275
202
  'return_on_capital_diff',
@@ -330,39 +257,57 @@ class Components:
330
257
 
331
258
  result_df['risk_free_rate'] = result_df['risk_free_rate'].apply(lambda x: f"{x:.2f} %")
332
259
 
260
+ div_padding = '5px'
261
+
333
262
  per_col_1_1.append(html.Div('Number of Trade', style={'background-color': 'darkblue' }))
334
- per_col_1_1.append(html.Div('Net Profit'))
335
- per_col_1_1.append(html.Div('Net Profit/MDD', style={'background-color': 'darkblue' }))
336
- per_col_1_1.append(html.Div('Return-BaH % Diff.'))
337
- per_col_1_1.append(html.Div('Win Rate', style={'background-color': 'darkblue' }))
338
- per_col_1_1.append(html.Div('COV (Count)'))
339
- per_col_1_1.append(html.Div('COV (Return)', style={'background-color': 'darkblue' }))
340
- per_col_1_1.append(html.Div('Total Commission'))
341
- per_col_1_1.append(html.Div('Risk Free Rate', style={'background-color': 'darkblue' }))
342
-
343
- per_col_2_1.append(html.Div('Return on Capital'))
344
- per_col_2_1.append(html.Div('Ann. Return', style={'background-color': 'darkblue' }))
345
- per_col_2_1.append(html.Div('Ann. Std'))
346
- per_col_2_1.append(html.Div('Ann. Sharpe Ratio', style={'background-color': 'darkblue' }))
347
- per_col_2_1.append(html.Div('MDD Dollar'))
348
- per_col_2_1.append(html.Div('MDD Percentage', style={'background-color': 'darkblue' }))
349
-
350
- for i in range(9):
263
+ per_col_1_1.append(html.Div('Correlation'))
264
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
265
+
266
+ per_col_1_1.append(html.Div('Net Profit', style={'background-color': 'darkblue' }))
267
+ per_col_1_1.append(html.Div('Net Profit/MDD'))
268
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
269
+
270
+ per_col_1_1.append(html.Div('Return-BaH % Diff.', style={'background-color': 'darkblue' }))
271
+ per_col_1_1.append(html.Div('Win Rate'))
272
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
273
+
274
+ per_col_1_1.append(html.Div('COV (Count)', style={'background-color': 'darkblue' }))
275
+ per_col_1_1.append(html.Div('COV (Return)'))
276
+ per_col_1_1.append(html.Div(style={'height': div_padding}))
277
+
278
+ per_col_1_1.append(html.Div('Total Commission', style={'background-color': 'darkblue' }))
279
+ per_col_1_1.append(html.Div('Risk Free Rate'))
280
+
281
+ per_col_2_1.append(html.Div('Return on Capital', style={'background-color': 'darkblue' }))
282
+ per_col_2_1.append(html.Div('Ann. Return'))
283
+ per_col_2_1.append(html.Div(style={'height': div_padding}))
284
+ per_col_2_1.append(html.Div('Ann. Std', style={'background-color': 'darkblue' }))
285
+ per_col_2_1.append(html.Div('Ann. Sharpe Ratio'))
286
+ per_col_2_1.append(html.Div(style={'height': div_padding}))
287
+ per_col_2_1.append(html.Div('MDD Dollar', style={'background-color': 'darkblue' }))
288
+ per_col_2_1.append(html.Div('MDD Percentage'))
289
+
290
+ for i in range(10):
351
291
  content = result_df.iloc[0][keys[i]]
352
292
  if i%2 == 1:
353
293
  per_col_1_2.append(html.Div(content, style={'text-align': 'center', }))
294
+ per_col_1_2.append(html.Div(style={'height': div_padding}))
354
295
  else:
355
- per_col_1_2.append(html.Div(content, style={'text-align': 'center','background-color': 'darkblue' }))
356
- for i in range(9, 15):
296
+ per_col_1_2.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}))
297
+
298
+ for i in range(10, 16):
357
299
  content = result_df.iloc[0][keys[i]]
358
300
  if i%2 == 1:
359
301
  per_col_2_2.append(html.Div(content, style={'text-align': 'center'}),)
302
+ per_col_2_2.append(html.Div(style={'height': div_padding}))
360
303
  else:
361
304
  per_col_2_2.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}),)
362
- for i in range(15, 21):
305
+
306
+ for i in range(16, 22):
363
307
  content = result_df.iloc[0][keys[i]]
364
308
  if i%2 == 1:
365
309
  per_col_2_3.append(html.Div(content, style={'text-align': 'center'}))
310
+ per_col_2_3.append(html.Div(style={'height': div_padding}))
366
311
  else:
367
312
  per_col_2_3.append(html.Div(content, style={'text-align': 'center', 'background-color': 'darkblue'}))
368
313
 
@@ -443,12 +388,12 @@ class Components:
443
388
  for idx , key in enumerate(para_keys_list):
444
389
  if idx%2 == 0:
445
390
  title.append(dbc.Row(
446
- [dbc.Col(key,width=6),
447
- dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center'},width=6)]))
391
+ [dbc.Col(key,width=6, style={ 'background-color': 'darkblue', 'marginBottom': '6px'}),
392
+ dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center', 'marginBottom': '6px', 'background-color': 'darkblue'},width=6)]))
448
393
  else:
449
394
  title.append(dbc.Row(
450
- [dbc.Col(key,width=6, style={ 'background-color': 'darkblue'}),
451
- dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center', 'background-color': 'darkblue'},width=6)]))
395
+ [dbc.Col(key,width=6),
396
+ dbc.Col(f'{result_df.iloc[0][key]}',style={ 'text-align': 'center'},width=6)]))
452
397
 
453
398
  matrix_div = html.Div([
454
399
  html.Div(style={'height': '8px', }),
@@ -457,6 +402,8 @@ class Components:
457
402
  html.Div('Selected Curve', style={'color': 'Cyan',
458
403
  'display': 'inline',
459
404
  'font-size': '15px'}),
405
+ html.Div(style={'height': '1px', }),
406
+
460
407
  html.Div('', id='save_status',
461
408
  style={'color': 'Cyan',
462
409
  'display': 'inline',
@@ -469,10 +416,12 @@ class Components:
469
416
  html.Div(style={'height': '15px', }),
470
417
 
471
418
  html.Div('Performance', style={'color': 'Cyan', 'font-size': '15px'}),
419
+ html.Div(style={'height': '2px', }),
472
420
  html.Div(children=per_col1, style={'font-size': '11px','padding-left':'1px'}),
473
421
  html.Div(style={'height': '15px', }),
474
422
 
475
423
  html.Div('Comparison', style={'color': 'Cyan', 'font-size': '15px'}),
424
+ html.Div(style={'height': '1px', }),
476
425
  html.Div(children=per_col2, style={'font-size': '11px','padding-right': '10px','padding-left':'1px'}),
477
426
  html.Div(style={'height': '15px', }),
478
427
 
@@ -507,6 +456,7 @@ class Components:
507
456
  'cov_return': 'COV (Return)',
508
457
  'win_rate':'Win Rate',
509
458
  'return_on_capital_diff': 'Return/BnH % Diff.',
459
+ 'correlation': 'Correlation',
510
460
  #'exclude': 'Exclude',
511
461
  }
512
462
 
@@ -558,12 +508,11 @@ class Components:
558
508
  return df_checked
559
509
 
560
510
  def assign_colour(self, profile, degree):
561
- if profile == 0: rgb = (0, int(252 - 252 * degree), 252)
511
+ if profile == 0: rgb = (0, int(252 - 252 * degree), 0)
562
512
  elif profile == 1: rgb = (int(252 - 252 * degree), 252, 0)
563
- elif profile == 2: rgb = (252, 0, int(252 - 252 * degree))
564
- elif profile == 3: rgb = (0, 252, int(252 * degree))
565
- elif profile == 4: rgb = (252, int(252 * degree), 0)
566
- elif profile == 5: rgb = (int(252 * degree), 0, 252)
513
+ elif profile == 2: rgb = (252, 0, int(round((252 - 252 * degree)/3)))
514
+ elif profile == 3: rgb = (0, 252, int(round((252 - 252 * degree)/3)))
515
+ elif profile >= 4: rgb = (252, int(252 * degree), 0)
567
516
  return 'rgb' + str(rgb)
568
517
 
569
518
  def generate_main_chart(self, graph_df, backtest_name, equity_curve_folder, para_keys_list):
@@ -767,28 +716,6 @@ class Components:
767
716
 
768
717
  return fig_line
769
718
 
770
- ### for class signal ###
771
- def generate_df_stat(self, df, period):
772
- col_pct = 'pct_change_' + str(period)
773
- col_rise = 'max_rise_' + str(period)
774
- col_fall = 'max_fall_' + str(period)
775
- df_his = df.copy()
776
- df_his[col_pct] = df_his['close'].pct_change(period)
777
- df_his[col_pct] = df_his[col_pct].shift(-1 * period)
778
- df_his[col_pct] = df_his[col_pct] * 100
779
- df_his[col_pct] = df_his[col_pct].map(lambda x: round(x, 2))
780
- df_his[col_rise] = (df_his['high'].rolling(period).max().shift(-1 * (period)) / df_his['close']) - 1
781
- df_his[col_fall] = (df_his['low'].rolling(period).min().shift(-1 * (period)) / df_his['close']) - 1
782
-
783
- df_his = df_his[df_his['logic'] == 'trade_logic']
784
-
785
- df_his[col_rise] = df_his[col_rise] * 100
786
- df_his[col_fall] = df_his[col_fall] * 100
787
-
788
- df_his[col_rise] = df_his[col_rise].map(lambda x: round(x, 2))
789
- df_his[col_fall] = df_his[col_fall].map(lambda x: round(x, 2))
790
-
791
- return round(df_his[col_pct].mean(), 2), round(df_his[col_rise].mean(), 2), round(df_his[col_fall].mean(), 2)
792
719
 
793
720
  def aggregate_df(self):
794
721
  all_str_dir = []
@@ -13,7 +13,7 @@ import os
13
13
 
14
14
  class Plot:
15
15
 
16
- filter_list = []
16
+ #filter_list = []
17
17
  add_filter_btn_count = 0
18
18
  main_chart_btn_clicks = 0
19
19
  stra_alys_chart_btn_clicks = 0
@@ -24,7 +24,7 @@ class Plot:
24
24
  select_all_status = False
25
25
 
26
26
 
27
- def __new__(self, backtest_result_df, number_of_curves):
27
+ def __new__(self, backtest_result_df, number_of_curves, filter_list= []):
28
28
 
29
29
  self.chart_bg = '#1f2c56'
30
30
  self.init_chart = True
@@ -49,6 +49,9 @@ class Plot:
49
49
  para_keys_str = self.backtest_result_dict[self.backtest_result_key[0]]['para_keys_str']
50
50
  self.para_keys_list = para_keys_str.split('|')
51
51
 
52
+ self.filter_list = filter_list
53
+ self.init_filter = True if len(self.filter_list) >0 else False
54
+
52
55
  components = Components(number_of_curves)
53
56
 
54
57
  self.start_year = datetime.datetime.strptime(self.start_date, '%Y-%m-%d').year
@@ -116,7 +119,7 @@ class Plot:
116
119
  dbc.Col(html.Div([
117
120
  html.Div(style={'height': '15px', }),
118
121
  html.Div('Sorting Method', style={'color': 'Cyan', 'margin-left': '15px', 'font-size': '15px'}),
119
- html.Div(style={'height': '10px', }),
122
+ html.Div(style={'height': '22px', }),
120
123
  sort_method_dropdown,
121
124
  html.Div(style={'height': '15px', }),
122
125
  html.Div('Parameters', style={'color': 'Cyan', 'margin-left': '15px', 'font-size': '15px'}),
@@ -247,7 +250,7 @@ class Plot:
247
250
  if not add_filter_btn_clicks:
248
251
  if not main_chart_btn_click:
249
252
  #self.sort_method_current = sort_method
250
- self.filter_list = []
253
+ #self.filter_list = []
251
254
  self.add_filter_btn_count = 0
252
255
  self.stra_alys_chart_btn_clicks = 0
253
256
  self.save_clicks = 0
@@ -258,25 +261,27 @@ class Plot:
258
261
  filter_input_div = filter_input
259
262
 
260
263
  ######################################################################
264
+ ########################### filter reaction ##########################
261
265
 
262
- if add_filter_btn_clicks:
263
- if add_filter_btn_clicks > self.add_filter_btn_count: ## Add btn Pressed
264
- self.add_filter_btn_count = add_filter_btn_clicks
265
- if filter_name:
266
- if filter_input_value:
267
- if filter_name == 'exclude':
268
- self.filter_list.append(['exclude', ' ', filter_input_value])
269
- else:
270
- self.filter_list.append([filter_name[0:-1], filter_name[-1], filter_input_value])
271
- filter_div = components.update_filter_div(self.filter_list)
272
- if len(self.filter_list) > 11:
273
- filter_dropdown_div = filter_dropdown_disabled
274
- filter_input_div = filter_input_disabled
275
- _add_filter_save_btn_style = add_filter_save_btn_style_disabled
276
- else:
277
- filter_dropdown_div = filter_dropdown
278
- filter_input_div = filter_input
279
- self.init_chart = False
266
+ if add_filter_btn_clicks != None and self.add_filter_btn_count!= None:
267
+ add_filter_btn_clicked = add_filter_btn_clicks > self.add_filter_btn_count
268
+ else:
269
+ add_filter_btn_clicked = False
270
+
271
+ if add_filter_btn_clicked or self.init_filter: ## Add btn Pressed
272
+ if not self.init_filter: self.add_filter_btn_count = add_filter_btn_clicks
273
+ if (filter_name != None and filter_input_value != None) or self.init_filter:
274
+ if not self.init_filter: self.filter_list.append([filter_name[0:-1], filter_name[-1], filter_input_value])
275
+ filter_div = components.update_filter_div(self.filter_list)
276
+ if len(self.filter_list) > 11:
277
+ filter_dropdown_div = filter_dropdown_disabled
278
+ filter_input_div = filter_input_disabled
279
+ _add_filter_save_btn_style = add_filter_save_btn_style_disabled
280
+ else:
281
+ filter_dropdown_div = filter_dropdown
282
+ filter_input_div = filter_input
283
+ self.init_chart = False
284
+ self.init_filter = False
280
285
 
281
286
  else:
282
287
  self.add_filter_btn_count = 0 # Necessary for initialization
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotguy
3
- Version: 2.2.4
3
+ Version: 2.3.0
4
4
  Summary: Plotguy
5
5
  Home-page: https://pypi.org/project/plotguy/
6
6
  Author: Plotguy Team
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="plotguy",
8
- version="2.2.4",
8
+ version="2.3.0",
9
9
  author="Plotguy Team",
10
10
  author_email="plotguy.info@gmail.com",
11
11
  description="Plotguy",
File without changes
File without changes
File without changes