template_analyze.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. use std::fs::File;
  2. use std::io::Write;
  3. use handlebars::Handlebars;
  4. use rust_decimal::Decimal;
  5. use tracing::info;
  6. #[allow(dead_code)]
  7. //生成html
  8. pub fn export_html(title: &str, symbol: &str, x_values: Vec<Decimal>, y_values: Vec<Decimal>) {
  9. info!("正在生成网页,请稍候……");
  10. let path = format!("./新版无敌大数据ticker {}.html", symbol);
  11. // 创建 Handlebars 实例
  12. let mut handlebars = Handlebars::new();
  13. let data = serde_json::json!({
  14. "chart_title": format!("新版无敌大数据Ticker {}的{}", title, symbol),
  15. "x_values": x_values,
  16. "y_values": y_values,
  17. });
  18. // HTML 模板
  19. let template = r#"
  20. <!DOCTYPE html>
  21. <html>
  22. <head>
  23. <meta charset="UTF-8">
  24. <title>{{chart_title}}</title>
  25. <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
  26. <script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js"></script>
  27. <style>
  28. * {
  29. margin: 0;
  30. padding: 0;
  31. }
  32. #main {
  33. margin: 50px auto 0;
  34. width: calc(100vw - 100px);
  35. height: calc(100vh - 100px);
  36. }
  37. .info_wp{
  38. padding: 0 40px;
  39. }
  40. </style>
  41. </head>
  42. <body>
  43. <div id="main"></div>
  44. <div class="info_wp">{{statistic_result}}</div>
  45. </body>
  46. <script>
  47. var exchangeColor = {binance: '#F4BC0C', gate: '#0068FF', okx: '#171F30'};
  48. var chartDom = document.getElementById('main');
  49. var myChart = echarts.init(chartDom);
  50. var option;
  51. option = {
  52. title: {
  53. text: '{{chart_title}}'
  54. },
  55. tooltip: {
  56. trigger: 'axis',
  57. axisPointer: {
  58. type: 'cross',
  59. lineStyle: {
  60. type: 'dashed',
  61. width: 1
  62. }
  63. },
  64. formatter: function (value) {
  65. let time = dayjs(value[0].name *1).format('YYYY-MM-DD HH:mm:ss.SSS');
  66. let price = value[0].value;
  67. return `时间:${time}<br/>价格:${price}`
  68. },
  69. },
  70. toolbox: {
  71. feature: {
  72. brush: {
  73. type: ['rect', 'clear']
  74. }
  75. }
  76. },
  77. dataZoom: [
  78. {
  79. type: 'inside',
  80. start: 0,
  81. end: 100
  82. },
  83. {
  84. start: 0,
  85. end: 100
  86. }
  87. ],
  88. legend: {
  89. data: {{x_values}}
  90. },
  91. xAxis: {
  92. type: 'category',
  93. boundaryGap: false,
  94. data: {{x_values}},
  95. show : false
  96. },
  97. yAxis: {
  98. type: 'value',
  99. boundaryGap: [0, '100%'],
  100. formatter: function (value) {
  101. return dayjs(value[0].name *1).format('YYYY-MM-DD HH:mm:ss.SSS');
  102. },
  103. },
  104. series: [
  105. {
  106. name: '价格',
  107. type: 'line',
  108. symbol: 'none',
  109. sampling: 'lttb',
  110. itemStyle: {
  111. color: 'rgb(55, 162, 255)'
  112. },
  113. areaStyle: {
  114. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  115. {
  116. opacity: 0.4,
  117. offset: 0,
  118. color: 'rgb(55, 162, 255)'
  119. },
  120. {
  121. opacity: 0.1,
  122. offset: 1,
  123. color: 'rgb(55, 162, 255)'
  124. }
  125. ])
  126. },
  127. data: {{y_values}}
  128. }
  129. ]
  130. };
  131. option && myChart.setOption(option);
  132. </script>
  133. </html>
  134. "#;
  135. // 编译模板
  136. handlebars
  137. .register_template_string("page", template)
  138. .expect("编译模版失败!");
  139. // 渲染模板
  140. let output = handlebars
  141. .render("page", &data)
  142. .expect("渲染模版失败!");
  143. // 将 HTML 写入文件
  144. let mut file = File::create(&path).expect("创建文件失败!");
  145. file.write_all(output.as_bytes()).expect("写入文件到本地失败!");
  146. info!("Analyze信息网页生成成功!路径:{:?}\n\n", path);
  147. }