首页 > 解决方案 > Chart.js 带度数

问题描述

我正在尝试在 x 轴为方位角(度)且 y 轴为仰角(度)的图表上绘制一些数据。我不确定问题是什么,但我猜这与我试图从 359 度到 20 度的数据范围有关

当没有环绕时,图表看起来很好,数据如下:

https://ibb.co/9TX5p5G

Zone     Az Start     Az Stop     Elevation
1           0          359           1.7
2          173         197           9.6           
3          206         216           3.2
4          217         300           3.7
5          341         351           4.6

但是,当我使用像这样环绕 360 度的数据时(参见区域 2),图表无法正确显示

Zone     Az Start     Az Stop     Elevation
1           0          359           1.3
2          359         20            6.4           
3          28          43            5.5
4          288         302           5.5
5          351         354           2.8

StackOverflow 不允许我发布图表的图像,但这是我的代码:

https://ibb.co/kxn5mqm

视图.py

def data_tiz(request):
    # Get the current URL we are on (it says what site we want TIZ data for)
    tiz_site = request.path.split('/')[3]
    current_day = datetime.now()
    # Gather all TIZ objects that live in the DB
    all_tiz_values = Tiz.objects.all() 
    # Initiate empty arrays
    tiz_to_display = []
    future_tiz_to_display = []
    zones = []
    # For each TIZ oject...
    for object in all_tiz_values:
        # If the site that the TIZ object belongs to is equal to the site the user is requetsing
        if str(tiz_site) in str(object.stationid):
                # Convert dates to comparable form to see if the TIZ is still active (or perm - perm tiz DO NOT have a .expiration_date
               obj_effect_date = object.effective_datetime
               obj_effect_date_format = datetime.strptime(str(obj_effect_date), '%Y-%m-%d')
               obj_exp_date_format = object.expiration_datetime
               # If the object does not have an end date, check to see if it is permanent (it should be)
               if obj_exp_date_format == None and str(object.is_permanent) == 'Y':
                   # If the object zone does not yet have a perm TIZ, append this object so that it now does
                   if object.tiz_zone not in zones:
                       tiz_to_display.append(object)
                       zones.append(object.tiz_zone)
                    # If there is already a TIZ in the same zone
                   else:
                       for entry in tiz_to_display:
                           entry_effect_date = entry.effective_datetime
                           entry_effect_date_format = datetime.strptime(str(obj_effect_date), '%Y-%m-%d')
                           # Pick the newest TIZ between the two (if a temp TIZ is active, it's effective date shoulud be higher then perm TIZ, so the perm TIZ should not overwrite the temp TIZ)
                           if entry.tiz_zone == object.tiz_zone and entry_effect_date_format < obj_effect_date_format:
                               tiz_to_display.remove(entry)
                               tiz_to_display.append(object)
                # If the object does have an end date (it's a temp TIZ), we need to determine if it's a past, current, or future temp tiz
               else:
                   obj_exp_date = datetime.strptime(str(obj_exp_date_format), '%Y-%m-%d')
                   # If the object expiration date doesn't expire until the future (after the current date)....
                   print(str(obj_exp_date) +  ' < ' + str(current_day) + ' and ' + str(obj_effect_date_format) + ' > ' + str(current_day))
                   if obj_exp_date > current_day and obj_effect_date_format <= current_day:
                    if object.tiz_zone not in zones:
                        tiz_to_display.append(object)
                    else:
                        for entry in tiz_to_display:
                           entry_exp_date_format = entry.expiration_datetime
                           print("asdfasdf")
                           if entry_exp_date_format == None and entry.tiz_zone == object.tiz_zone:
                               tiz_to_display.remove(entry)
                               tiz_to_display.append(object) 
                    # Else, this means that it is a FUTURE temp tiz, so we can append to that array
                   elif obj_exp_date > current_day and obj_effect_date_format > current_day:
                       future_tiz_to_display.append(object)
    # sort TIZ by zone number
    tiz_to_display.sort(key=lambda x: x.tiz_zone, reverse=False)
    # Get number of zones for the graph
    num_zones = len(tiz_to_display)
    future_num_zones = len(future_tiz_to_display)
    

    return render(request, 'webdart/tizHTML.html', {'future_num_zones': future_num_zones, 'num_zones': num_zones, 'future_tiz_to_display': future_tiz_to_display, 'all_tiz_values': all_tiz_values, 'tiz_site': tiz_site, 'tiz_to_display': tiz_to_display});

tizHTML.html

{% load static %}
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
        <link rel="stylesheet" href="{% static 'css/main.css' %}" />
    </head>
    <body class="site_data_body">          
        <br>
        <label for="HTSA-TizDT">Date/Time:</label>
        <input type="datetime-local" id="HTSA-TizDT" class="site_data_input" name="HTSA-TizDT"><br>
        <h3 style="display:inline;">Download Zones: </h3>
        <a href="#" class="download_link">CSV</a><br>
        <h3 style="display:inline;">Download 0-359 Values: </h3>
        <a href="#" class="download_link">CSV</a>
        <h3 style="display:inline;"> | </h3>
        <a href="#" class="download_link">STK</a><br><br>
        <h3>Current Operational TIZ</h3>
        <button type="button" class="hide_table_button" data-toggle="collapse" data-target="#tizCurrentTableCollapsible" href="#tizCurrentTableCollapsible">Show/Hide Table</button>
        <div id="tizCurrentTableCollapsible" class="collapse">
            <table class="table data_table table-striped">
                <thead class="thead-dark">
                    <tr>
                        <th>Zone</th>
                        <th>Az Start</th>
                        <th>Az Stop</th>
                        <th>Elevation</th>
                        <th>Effective Date</th>
                        <th>End Date</th>
                        <th>Comments</th>
                    </tr>
                </thead>
                <tbody>
                     {% for object in tiz_to_display %} 
           <tr>
                        <td>{{ object.tiz_zone }}</td>
                        <td>{{ object.start_az }}</td>
                        <td>{{ object.end_az }}</td>
                        <td>{{ object.elevation }}</td>
                        <td>{{ object.effective_datetime }}</td>
                        <td>{{ object.expiration_datetime }}</td>
                        <td>{{ object.comments }}</td>
                    </tr>                   
                    {% endfor %}                   
                </tbody>
            </table>
        </div>
        <!-- Chart 1 -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js" integrity="sha512-asxKqQghC1oBShyhiBwA+YgotaSYKxGP1rcSYTDrB0U6DxwlJjU59B67U8+5/++uFjcuVM8Hh5cokLjZlhm3Vg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <center><canvas id="tizCurrentChart" class="data_chart"></canvas></center><br><br>
        <script>        
            var zones = {{ num_zones }};
            var inputs = []
            {% for object in tiz_to_display %}
                var input{{ forloop.counter }} =[{{ object.start_az }}, {{ object.end_az }}, {{ object.elevation }}]
                inputs.push(input{{ forloop.counter }})

            {% endfor %}
            var datasets = new Array(zones);
            for (var i = 0; i < zones; i++) {
                var start = inputs[i][0];
                var end = inputs[i][1];
                var val = inputs[i][2];
                var data = [];
                for (var j = 0; j <= (end - start); j++) {
                    data[j] = {x: j + start, y: val};
                }
                datasets[i] = data;
            }
            //Animation
            var totalDuration = 3000;
            var stepsize = totalDuration / datasets[0].length;
            var previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;
            var animation = {
                x: {
                    type: 'number',
                    easing: 'linear',
                    duration: stepsize,
                    from: NaN, // the point is initially skipped
                    delay(ctx) {
                        if (ctx.type !== 'data' || ctx.xStarted) {
                            return 0;
                        }
                        ctx.xStarted = true;
                        return ctx.index * stepsize;
                    }
                },
                y: {
                    type: 'number',
                    easing: 'linear',
                    duration: stepsize,
                    from: previousY,
                    delay(ctx) {
                        if (ctx.type !== 'data' || ctx.yStarted) {
                            return 0;
                        }
                        ctx.yStarted = true;
                        return ctx.index * stepsize;
                    }
                }
            };
            //Chart Creation
            var color1 = 'rgba(0,0,128,0.6)'
            var color2 = 'rgba(128,0,0,0.6)'
            var color3 = 'rgba(0,128,0,0.6)'
            var color4 = 'rgba(128,128,0,0.6)'
            var color5 = 'rgba(128,0,128,0.6)'
            var color6 = 'rgba(128,128,128,0.6)'
            var ctx = document.getElementById('tizCurrentChart').getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'line',
                data: {
                    datasets: [
                        {% for object in tiz_to_display %}
                {
                    label: 'Zone {{ forloop.counter }}',
                    borderColor: 'rgba(0,0,128,1)',
                    backgroundColor: window['color{{ forloop.counter }}'],
                        borderWidth: 1,
                        radius: 0,
                data: datasets[{{ forloop.counter0 }}],
                        fill: 'origin'
                    },
            {% endfor %}
                  ]
                },
                options: {
                    animation,
                    interaction: {
                        intersect: false
                    },
                    plugins: {
                        title: {
                            display: true,
                            text: 'Current Site TIZ'
                        }
                    },
                    scales: {
                        x: {
                            type: 'linear',
                            title: { display: true, text: 'Azimuth (degrees)' },
                            max: 360,
                            ticks: {
                                  min: 0,
                                  max: 100,

                                  // forces step size to be 5 units
                                  stepSize: 5 // <----- This prop sets the stepSize
    }
                        },

                        y: {
                            title: {display: true, text: 'Elevation (degrees)'},
                            min: 0
                        }
                    }
                }
            });
        </script>
    </body>
</html>

关于如何将输入环绕 360 度的任何想法?如果我能弄清楚,我会继续尝试发布图像。

我目前唯一的想法是将两个拆分为两个单独的数据集以绘制图形。这并不理想,因为我希望每个区域在图表上都是相同的颜色

标签: javascriptdjangodjango-viewsdjango-templateschart.js

解决方案


推荐阅读