diff --git a/wwwroot/sect_currency.ui b/wwwroot/sect_currency.ui index 57b195b..988b335 100644 --- a/wwwroot/sect_currency.ui +++ b/wwwroot/sect_currency.ui @@ -1,11 +1,20 @@ {% set data = j2_currency_data(request) %} -{% set chart_data = [] %}{% for r in data %}{% set _ = chart_data.append({"name": r.get("currency",""), "value": r.get("call_count",0)}) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_currency'));c.setOption({tooltip:{trigger:'item'},series:[{type:'pie',radius:['45%','70%'],center:['50%','55%'],data:{{json.dumps(chart_data,ensure_ascii=False)}},label:{show:true,formatter:'{b} {c}次({d}%)'}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} +{% if data %}{% set maxv = namespace(v=0) %}{% for r in data %}{% if r.get("call_count",0)|int > maxv.v %}{% set maxv.v = r.get("call_count",0)|int %}{% endif %}{% endfor %}{% endif %} { - "widgettype": "WebWidget", - "options": { - "height": "200px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {% for r in data %} + {% set name = r.get("currency","") %}{% set val = r.get("call_count",0)|int %}{% set pct = (val/maxv.v*100)|int if maxv.v else 0 %} + {"widgettype":"VBox","options":{"width":"100%","marginBottom":"4px"},"subwidgets":[ + {"widgettype":"HBox","options":{"width":"100%"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(name,ensure_ascii=False)}},"width":"15%","fontSize":"11px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(val|string+'次',ensure_ascii=False)}},"width":"13%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}}, + {"widgettype":"VBox","options":{"width":"60%","height":"14px","bgcolor":"var(--sage-bg-tertiary)","borderRadius":"3px"},"subwidgets":[ + {"widgettype":"VBox","options":{"width":"{{pct}}%","minWidth":"2px","height":"14px","bgcolor":"#f59e0b","borderRadius":"3px"}} + ]}, + {"widgettype":"Text","options":{"text":{{json.dumps(pct|string+'%',ensure_ascii=False)}},"width":"12%","fontSize":"10px","textAlign":"right","color":"var(--sage-text-tertiary)"}} + ]} + ]}{% if not loop.last %},{% endif %}{% endfor %} + ] } diff --git a/wwwroot/sect_model_perf.ui b/wwwroot/sect_model_perf.ui index 9316ffb..9f11c36 100644 --- a/wwwroot/sect_model_perf.ui +++ b/wwwroot/sect_model_perf.ui @@ -1,11 +1,19 @@ {% set data = j2_model_perf_data(request) %} -{% set names = [] %}{% set vals = [] %}{% for r in data %}{% set _ = names.append(r.get("model","")) %}{% set _ = vals.append(r.get("avg_latency_ms",0)|float) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_model_perf'));c.setOption({tooltip:{trigger:'axis',formatter:function(p){return p[0].name+'
延迟: '+p[0].value+'ms'}},grid:{left:10,right:40,top:5,bottom:5,containLabel:true},xAxis:{type:'value',name:'ms',axisLabel:{fontSize:10}},yAxis:{type:'category',data:{{json.dumps(names,ensure_ascii=False)}},inverse:true,axisLabel:{fontSize:11}},series:[{type:'bar',data:{{json.dumps(vals,ensure_ascii=False)}},barMaxWidth:18,label:{show:true,position:'right',formatter:'{c}ms',fontSize:10},itemStyle:{borderRadius:[0,4,4,0]}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} +{% if data %}{% set maxv = namespace(v=0) %}{% for r in data %}{% if r.get("avg_latency_ms",0)|float > maxv.v %}{% set maxv.v = r.get("avg_latency_ms",0)|float %}{% endif %}{% endfor %}{% endif %} { - "widgettype": "WebWidget", - "options": { - "height": "180px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {% for r in data %} + {% set name = r.get("model","") %}{% set val = r.get("avg_latency_ms",0)|float %}{% set pct = (val/maxv.v*100)|int if maxv.v else 0 %} + {"widgettype":"VBox","options":{"width":"100%","marginBottom":"4px"},"subwidgets":[ + {"widgettype":"HBox","options":{"width":"100%"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(name,ensure_ascii=False)}},"width":"32%","fontSize":"11px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(val|string+'ms',ensure_ascii=False)}},"width":"12%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}}, + {"widgettype":"VBox","options":{"width":"56%","height":"14px","bgcolor":"var(--sage-bg-tertiary)","borderRadius":"3px"},"subwidgets":[ + {"widgettype":"VBox","options":{"width":"{{pct}}%","minWidth":"2px","height":"14px","bgcolor":"#3b82f6","borderRadius":"3px"}} + ]} + ]} + ]}{% if not loop.last %},{% endif %}{% endfor %} + ] } diff --git a/wwwroot/sect_provider_roi.ui b/wwwroot/sect_provider_roi.ui index c402505..780a2e9 100644 --- a/wwwroot/sect_provider_roi.ui +++ b/wwwroot/sect_provider_roi.ui @@ -1,11 +1,23 @@ {% set data = j2_provider_roi_data(request) %} -{% set bubble_data = [] %}{% for r in data %}{% set _ = bubble_data.append([r.get("unit_price",0)|float, r.get("avg_ttft_ms",0)|float, r.get("total_calls",0)|int, r.get("model","")]) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_provider_roi'));c.setOption({tooltip:{trigger:'item',formatter:function(p){return p.data[3]+'
单价:'+p.data[0]+'/t
延迟:'+p.data[1]+'ms
调用:'+p.data[2]+'次'}},xAxis:{type:'value',name:'单价(¥/t)',nameLocation:'center',nameGap:25},yAxis:{type:'value',name:'延迟(ms)',nameLocation:'center',nameGap:35},series:[{type:'scatter',symbolSize:function(d){return Math.max(8,Math.sqrt(d[2])*0.5)},data:{{json.dumps(bubble_data,ensure_ascii=False)}},label:{show:true,formatter:function(p){return p.data[3]},position:'top',fontSize:10}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} { - "widgettype": "WebWidget", - "options": { - "height": "240px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {"widgettype":"HBox","options":{"cheight":2,"width":"100%","bgcolor":"var(--sage-bg-secondary)","borderRadius":"4px 4px 0 0","padding":"2px 8px"},"subwidgets":[ + {"widgettype":"Text","options":{"text":"模型","width":"30%","fontSize":"11px","color":"var(--sage-text-secondary)"}}, + {"widgettype":"Text","options":{"text":"单价","width":"18%","fontSize":"11px","color":"var(--sage-text-secondary)"}}, + {"widgettype":"Text","options":{"text":"延迟","width":"18%","fontSize":"11px","color":"var(--sage-text-secondary)"}}, + {"widgettype":"Text","options":{"text":"调用","width":"18%","fontSize":"11px","color":"var(--sage-text-secondary)"}}, + {"widgettype":"Text","options":{"text":"总金额","width":"16%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}} + ]} + {% for r in data %} + ,{"widgettype":"HBox","options":{"width":"100%","padding":"3px 8px"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(r.get("model",""),ensure_ascii=False)}},"width":"30%","fontSize":"12px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(r.get("unit_price",""),ensure_ascii=False)}},"width":"18%","fontSize":"12px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(r.get("avg_ttft_ms",""),ensure_ascii=False)}},"width":"18%","fontSize":"12px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(r.get("total_calls",""),ensure_ascii=False)}},"width":"18%","fontSize":"12px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps('¥'+(r.get("total_amount_cny",0)|string),ensure_ascii=False)}},"width":"16%","fontSize":"12px","textAlign":"right"}} + ]} + {% endfor %} + ] } diff --git a/wwwroot/sect_top_models.ui b/wwwroot/sect_top_models.ui index d79ac0e..b58c476 100644 --- a/wwwroot/sect_top_models.ui +++ b/wwwroot/sect_top_models.ui @@ -1,11 +1,17 @@ {% set data = j2_top_models_data(request) %} -{% set names = [] %}{% set vals = [] %}{% for r in data %}{% set _ = names.append(r.get("model_name","")) %}{% set _ = vals.append(r.get("cnt",0)) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_top_models'));c.setOption({tooltip:{trigger:'axis'},grid:{left:10,right:20,top:5,bottom:5,containLabel:true},xAxis:{type:'value'},yAxis:{type:'category',data:{{json.dumps(names,ensure_ascii=False)}},inverse:true,axisLabel:{fontSize:11}},series:[{type:'bar',data:{{json.dumps(vals,ensure_ascii=False)}},barMaxWidth:20,label:{show:true,position:'right',fontSize:11}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} +{% if data %}{% set maxv = namespace(v=0) %}{% for r in data %}{% if r.get("cnt",0)|int > maxv.v %}{% set maxv.v = r.get("cnt",0)|int %}{% endif %}{% endfor %}{% endif %} { - "widgettype": "WebWidget", - "options": { - "height": "200px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {% for r in data %} + {% set name = r.get("model_name","") %}{% set val = r.get("cnt",0)|int %}{% set pct = (val/maxv.v*100)|int if maxv.v else 0 %} + {"widgettype":"HBox","options":{"width":"100%","marginBottom":"4px"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(name,ensure_ascii=False)}},"width":"32%","fontSize":"11px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps(val|string+'次',ensure_ascii=False)}},"width":"12%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}}, + {"widgettype":"VBox","options":{"width":"56%","height":"14px","bgcolor":"var(--sage-bg-tertiary)","borderRadius":"3px"},"subwidgets":[ + {"widgettype":"VBox","options":{"width":"{{pct}}%","minWidth":"2px","height":"14px","bgcolor":"#10b981","borderRadius":"3px"}} + ]} + ]}{% if not loop.last %},{% endif %}{% endfor %} + ] } diff --git a/wwwroot/sect_top_providers.ui b/wwwroot/sect_top_providers.ui index 9742f35..01d0cd5 100644 --- a/wwwroot/sect_top_providers.ui +++ b/wwwroot/sect_top_providers.ui @@ -1,11 +1,17 @@ {% set data = j2_top_providers_data(request) %} -{% set names = [] %}{% set vals = [] %}{% for r in data %}{% set _ = names.append(r.get("provider_name","")) %}{% set _ = vals.append(r.get("total_amount",0)) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_top_providers'));c.setOption({tooltip:{trigger:'axis'},grid:{left:10,right:50,top:5,bottom:5,containLabel:true},xAxis:{type:'value'},yAxis:{type:'category',data:{{json.dumps(names,ensure_ascii=False)}},inverse:true,axisLabel:{fontSize:11}},series:[{type:'bar',data:{{json.dumps(vals,ensure_ascii=False)}},barMaxWidth:20,label:{show:true,position:'right',formatter:'¥{c}',fontSize:11}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} +{% if data %}{% set maxv = namespace(v=0) %}{% for r in data %}{% set amt = r.get("total_amount",0)|float %}{% if amt > maxv.v %}{% set maxv.v = amt %}{% endif %}{% endfor %}{% endif %} { - "widgettype": "WebWidget", - "options": { - "height": "200px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {% for r in data %} + {% set name = r.get("provider_name","") %}{% set val = r.get("total_amount",0)|float %}{% set pct = (val/maxv.v*100)|int if maxv.v else 0 %} + {"widgettype":"HBox","options":{"width":"100%","marginBottom":"4px"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(name,ensure_ascii=False)}},"width":"32%","fontSize":"11px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps('¥' + ('%.2f'%val),ensure_ascii=False)}},"width":"12%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}}, + {"widgettype":"VBox","options":{"width":"56%","height":"14px","bgcolor":"var(--sage-bg-tertiary)","borderRadius":"3px"},"subwidgets":[ + {"widgettype":"VBox","options":{"width":"{{pct}}%","minWidth":"2px","height":"14px","bgcolor":"#ef4444","borderRadius":"3px"}} + ]} + ]}{% if not loop.last %},{% endif %}{% endfor %} + ] } diff --git a/wwwroot/sect_top_users.ui b/wwwroot/sect_top_users.ui index a801652..b4e94c7 100644 --- a/wwwroot/sect_top_users.ui +++ b/wwwroot/sect_top_users.ui @@ -1,11 +1,17 @@ {% set data = j2_top_users_data(request) %} -{% set names = [] %}{% set vals = [] %}{% for r in data %}{% set _ = names.append(r.get("user_name","")) %}{% set _ = vals.append(r.get("total_amount",0)) %}{% endfor %} -{% set script %}(function(){var c=echarts.init(document.getElementById('chart_top_users'));c.setOption({tooltip:{trigger:'axis'},grid:{left:10,right:50,top:5,bottom:5,containLabel:true},xAxis:{type:'value'},yAxis:{type:'category',data:{{json.dumps(names,ensure_ascii=False)}},inverse:true,axisLabel:{fontSize:11}},series:[{type:'bar',data:{{json.dumps(vals,ensure_ascii=False)}},barMaxWidth:20,label:{show:true,position:'right',formatter:'¥{c}',fontSize:11}}]});window.addEventListener('resize',function(){c.resize()});})();{% endset %} +{% if data %}{% set maxv = namespace(v=0) %}{% for r in data %}{% set amt = r.get("total_amount",0)|float %}{% if amt > maxv.v %}{% set maxv.v = amt %}{% endif %}{% endfor %}{% endif %} { - "widgettype": "WebWidget", - "options": { - "height": "200px", - "html": "
", - "script": {{json.dumps(script, ensure_ascii=False)}} - } + "widgettype": "VBox", + "options": {"width": "100%"}, + "subwidgets": [ + {% for r in data %} + {% set name = r.get("user_name","") %}{% set val = r.get("total_amount",0)|float %}{% set pct = (val/maxv.v*100)|int if maxv.v else 0 %} + {"widgettype":"HBox","options":{"width":"100%","marginBottom":"4px"},"subwidgets":[ + {"widgettype":"Text","options":{"text":{{json.dumps(name,ensure_ascii=False)}},"width":"32%","fontSize":"11px"}}, + {"widgettype":"Text","options":{"text":{{json.dumps('¥' + ('%.2f'%val),ensure_ascii=False)}},"width":"12%","fontSize":"11px","textAlign":"right","color":"var(--sage-text-secondary)"}}, + {"widgettype":"VBox","options":{"width":"56%","height":"14px","bgcolor":"var(--sage-bg-tertiary)","borderRadius":"3px"},"subwidgets":[ + {"widgettype":"VBox","options":{"width":"{{pct}}%","minWidth":"2px","height":"14px","bgcolor":"#8b5cf6","borderRadius":"3px"}} + ]} + ]}{% if not loop.last %},{% endif %}{% endfor %} + ] }