Python 3.x Flask&Python:如何在Flask中使用格式HH:MM:SS.SSS绘制图表,其中x轴表示月份,y轴(数据)表示时间

Python 3.x Flask&Python:如何在Flask中使用格式HH:MM:SS.SSS绘制图表,其中x轴表示月份,y轴(数据)表示时间,python-3.x,flask,Python 3.x,Flask,我目前正在使用Flask和Chart.js生成图形。基本上我有一个数据库sqlite,它存储游泳比赛中获得的时间。时间是HH:MM:SS.SSS格式的,例如,在50米自由泳中,我没有问题,因为时间是SS.SS格式的,例如26.94,我可以用Chart.js在Flask中生成图形,因为我可以将26.94转换成一个数字,并得到一个x轴为数月的图形,y轴为26.94。然而,对于像00:08:23.78这样的时间,我需要在y轴上绘制该时间相对于x轴上达到该时间的月份的图表。我仍然无法想象Chart.js

我目前正在使用Flask和Chart.js生成图形。基本上我有一个数据库sqlite,它存储游泳比赛中获得的时间。时间是HH:MM:SS.SSS格式的,例如,在50米自由泳中,我没有问题,因为时间是SS.SS格式的,例如26.94,我可以用Chart.js在Flask中生成图形,因为我可以将26.94转换成一个数字,并得到一个x轴为数月的图形,y轴为26.94。然而,对于像00:08:23.78这样的时间,我需要在y轴上绘制该时间相对于x轴上达到该时间的月份的图表。我仍然无法想象Chart.js的解决方案。任何导游都会非常感激的。 Flask和Python中生成图形的源代码部分如下所示:

@app.route("/simple_chart")
def chart():
legend = 'Monthly performance at 50m Freestyle'
labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dic"]

values = [26.94, 26.70, 26.80, 27.40, 26.45, 26.43, 26.30, 26.25, 26.20, 26.35, 26.00, 25.00]
return render_template('chart.html', values=values, labels=labels, legend=legend)
 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="utf-8" />
 <title>Chart.js Example</title>
 <!-- import plugin script -->
 <script src='static/Chart.min.js'></script>
 </head>
 <body>
   <h1>50 m. Free Style</h1>
   <!-- bar chart canvas element -->
   <canvas id="myChart" width="600" height="400"></canvas>
   <p id="caption">Data obtained from swimming competitions.</p>

   <script>
     // Global parameters:
     // do not resize the chart canvas when its container does (keep at 600x400px)
     Chart.defaults.global.responsive = false;

     // define the chart data
     var chartData = {
       labels : [{% for item in labels %}
                  "{{item}}",
                 {% endfor %}],
       datasets : [{
        label: '{{ legend }}',
        fill: true,
        lineTension: 0.1,
        backgroundColor: "rgba(75,192,192,0.4)",
        borderColor: "rgba(75,192,192,1)",
        borderCapStyle: 'butt',
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        pointBorderColor: "rgba(75,192,192,1)",
        pointBackgroundColor: "#fff",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "rgba(75,192,192,1)",
        pointHoverBorderColor: "rgba(220,220,220,1)",
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        data : [{% for item in values %}
                  {{item}},
                {% endfor %}],
        spanGaps: false
       }]
     }

     // get chart canvas
     var ctx = document.getElementById("myChart").getContext("2d");

     // create the chart using the chart canvas
     var myChart = new Chart(ctx, {
       type: 'line',
       data: chartData,
     });
   </script>

 </body>
chart.html文件的源代码如下:

@app.route("/simple_chart")
def chart():
legend = 'Monthly performance at 50m Freestyle'
labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dic"]

values = [26.94, 26.70, 26.80, 27.40, 26.45, 26.43, 26.30, 26.25, 26.20, 26.35, 26.00, 25.00]
return render_template('chart.html', values=values, labels=labels, legend=legend)
 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="utf-8" />
 <title>Chart.js Example</title>
 <!-- import plugin script -->
 <script src='static/Chart.min.js'></script>
 </head>
 <body>
   <h1>50 m. Free Style</h1>
   <!-- bar chart canvas element -->
   <canvas id="myChart" width="600" height="400"></canvas>
   <p id="caption">Data obtained from swimming competitions.</p>

   <script>
     // Global parameters:
     // do not resize the chart canvas when its container does (keep at 600x400px)
     Chart.defaults.global.responsive = false;

     // define the chart data
     var chartData = {
       labels : [{% for item in labels %}
                  "{{item}}",
                 {% endfor %}],
       datasets : [{
        label: '{{ legend }}',
        fill: true,
        lineTension: 0.1,
        backgroundColor: "rgba(75,192,192,0.4)",
        borderColor: "rgba(75,192,192,1)",
        borderCapStyle: 'butt',
        borderDash: [],
        borderDashOffset: 0.0,
        borderJoinStyle: 'miter',
        pointBorderColor: "rgba(75,192,192,1)",
        pointBackgroundColor: "#fff",
        pointBorderWidth: 1,
        pointHoverRadius: 5,
        pointHoverBackgroundColor: "rgba(75,192,192,1)",
        pointHoverBorderColor: "rgba(220,220,220,1)",
        pointHoverBorderWidth: 2,
        pointRadius: 1,
        pointHitRadius: 10,
        data : [{% for item in values %}
                  {{item}},
                {% endfor %}],
        spanGaps: false
       }]
     }

     // get chart canvas
     var ctx = document.getElementById("myChart").getContext("2d");

     // create the chart using the chart canvas
     var myChart = new Chart(ctx, {
       type: 'line',
       data: chartData,
     });
   </script>

 </body>

附件是一张显示女子800米自由泳记录进展的图表截图

源代码在最合适的块中包含注释,以在必要时阐明实现

<!DOCTYPE html>

<html>

  <head>
  <meta charset="utf-8" />
  <title></title>
  <link rel="stylesheet" href="/static/style.css" />
  <script data-require="jquery" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://npmcdn.com/moment@2.14.1"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script> 
    
  <script>
      $(function(){
            const ctx = document.getElementById('myChart').getContext('2d'); 
        
            let years = [
                          "1978", 
                          "1978", 
                          "1987", 
                          "1987", 
                          "1988", 
                          "1989",
                          "2008", 
                          "2013",
                          "2014",
                          "2015",
                          "2016",
                          "2016"
            ];
        
            let times = [
                          "00:08:30.53", 
                          "00:08:24.62", 
                          "00:08:22.44", 
                          "00:08:19.53", 
                          "00:08:17.12", 
                          "00:08:16.22", 
                          "00:08:14.10", 
                          "00:08:13.86",
                          "00:08:11.00",
                          "00:08:07.39",
                          "00:08:06.68",
                          "00:08:04.79"
            ];
        
            let data = years.map((year, index) => ({
              x: moment(`${year}-01-01`), 
              y: moment(`1970-02-01 ${times[index]}`).valueOf()
            }));
        
            let bckColors = [
              "#66FF00", // Bright Green 
              "#1974D2", // Bright Navy Blue 
              "#08E8DE", // Bright Turquoise 
              "#FFF000", // Yellow Rose 
              "#FFAA1D", // Bright Yellow (Crayola)
              "#FF007F", // Bright Pink
              "#91aaff", 
              "#ff9e9e", 
              "#ff80c5", 
              "#7afbff",
              "#8aff9c",
              "#edc065"
            ];
        
            let myChart = new Chart(ctx, {
              type: 'line',
              data: {
              datasets: [{
                      label: "Time progression in the 800m. freestyle Women",
                      // SEE: https://encycolorpedia.com/
                      // to assign rgba() colors
                      // 'backgroundColor' fill color of the area under the curve that joins the points
                      backgroundColor: 'rgba(17, 67, 116, 0.6)',  // Sailboat Blue 0.6 reduce opacity
                                                                  // To reduce opacity SEE: https://stackoverflow.com/questions/45104743/draw-two-plots-using-chartjs-over-one-another-with-transparency
                      // 'borderColor' color of the line connecting the points
                      borderColor: 'rgba(254, 254, 250, 1.0)', // Baby Powder
                      pointBackgroundColor: bckColors,
                      data: data,
                      pointBorderWidth: 2,
                      pointRadius: 5,
                      pointHoverRadius: 7
                      
              }]
             },

             options:{
                 legend:{
                     labels:{
                         fontFamily:'Courier',
                         fontColor: 'black',
                         fontSize: 18
                     }
                 },
                 scales: {
                     xAxes:[{
                         type: 'time',
                         position: 'bottom',
                         time:{
                             displayFormats: {
                                 years: 'YYYY'
                             },
                          
                             unit: 'year'
                         },

                         ticks: {
                             fontFamily:'Courier',
                             fontColor: 'black',
                             fontSize: 12,
                             // Display the labels in x-Axis 
                             // jumping from three years to three years
                            
                             // SEE:https://stackoverflow.com/questions/61847921/chart-js-how-i-change-the-x-axes-ticks-labels-alignment-in-any-sizes
                             autoSkip: true,
                             autoSkipPadding: 75,
                         },
                                                
                         scaleLabel:{ 
                             // x-axis label
                             fontFamily:'Courier',
                             fontColor: 'black',
                             fontSize: 14,
                             display: true,
                             labelString: 'Year'
                         }
                     }],

                     yAxes:[{
                         type: 'linear',
                         position: 'left',
                         ticks:{
                             fontFamily:'Courier',
                             fontColor: 'black',
                             fontSize: 12,
                             // fix y-Axis time interval. 
                             // This interval must go from (mm:ss.SS)
                             // "00:00.00" to (mm:ss.SS) "10:00.00"
                             min: moment('1970-02-01 00:08:00.00').valueOf(),
                             max: moment('1970-02-01 00:08:31.00').valueOf(),                                                          
                                                        
                             beginAtZero:false,

                             callback: value => {
                                 let date = moment(value);                                           
                                                              
                                 if(date.diff(moment('1970-02-01 00:10:00.00'), 'seconds') === 0) {
                                                                                                                                              
                                     return null;
                                 }                                                                               
                                                                            
                             // SEE: https://flaviocopes.com/momentjs/                                               
                             // Moment provides a constant
                             // 'HTML5_FMT.TIME_MS'
                             // to format date as HH:mm:ss.SSS 
                             // Example: 16:34:10.234 
                                                                            
                                return moment(date,'HTML5_FMT.TIME_MS').format('mm:ss.SS')
                             }
                          },
                          scaleLabel:{ 
                              // y-axis label
                              fontFamily:'Courier',
                              fontColor: 'black',
                              fontSize: 14,
                              display: true,
                              labelString: 'Time'
                          }
                     }]
                 },
              
                 tooltips:{ 
                     callbacks:{
                         title: function(tooltipItems, data) {
                             // Return value for title (xlabel)
                             // SEE: callback function to change 
                             // title of tooltip (tooltipItems[0].xLabel)
                             // https://stackoverflow.com/questions/38819171/chart-js-2-0-how-to-change-title-of-tooltip
                                                                        
                                                                        
                             // SEE: https://flaviocopes.com/momentjs/
                             // Moment provides the functions to format
                             // tooltipItems[0].xLabel (Date) to 'YYYY' Example: 2016
                                                                        
                             return moment(tooltipItems[0].xLabel).format("YYYY")
                         },

                         label: function(tooltipItem, data) {
                             // Return value for (yLabel)
                             // SEE: callback function to convert timestamp (tooltipItem.yLabel) to mm:ss.SS
                             // https://stackoverflow.com/questions/19485353/function-to-convert-timestamp-to-human-date-in-javascript/34900794
                                                                        
                             return ' Time : ' + moment(tooltipItem.yLabel).format("mm:ss.SS")
                         },

                 }
            }
          }
        });
      });
   </script>
   </head>

   <body>
       <div class = "container">
           <canvas style = "background-color: grey;" id="myChart"></canvas>
       </div>
   </body>

看起来chart.js支持打印日期和时间。你不能把分钟转换成秒,并把它们也记录成一个数字吗?例如00:08:23.78>503.78[8*60+23.78]。您可以编写一个函数来实现这一点。这样做有什么问题吗?@noslenkwah-感谢noslenkwah指导我阅读chart.js文档。我仔细阅读了chart.js的文档,并回顾了stackoverflow的一些实现。最后,我终于按照自己的意愿画出了图表。我将包括代码的实现,以防它对具有类似需求的人有用。