javascript - Chart.js 带度数
问题描述
我正在尝试在 x 轴为方位角(度)且 y 轴为仰角(度)的图表上绘制一些数据。我不确定问题是什么,但我猜这与我试图从 359 度到 20 度的数据范围有关
当没有环绕时,图表看起来很好,数据如下:
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 不允许我发布图表的图像,但这是我的代码:
视图.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 度的任何想法?如果我能弄清楚,我会继续尝试发布图像。
我目前唯一的想法是将两个拆分为两个单独的数据集以绘制图形。这并不理想,因为我希望每个区域在图表上都是相同的颜色
解决方案
推荐阅读
- node.js - MongoDB/Mongoose:根据给定文档中的值进行搜索,而不首先返回该文档
- android - 二进制 XML 文件第 9 行:夸大类活动时出错
- php - 扩展 PHP 类以允许通过 __callStatic 找到新方法
- visual-studio-2019 - 我如何将两个表格堆叠在一起
- javascript - React-Redux,如何在渲染新组件之前设置全局状态?
- typescript - 试图为 TypeScript EventListeners 建立一个泛型类型并得到一个奇怪的错误
- flutter - 为什么我不能在颤振中访问 Firestore 值?
- r - 将大型 zip tsv 文件导入 R 时出现内存问题
- reactjs - Redirect from 在反应路由器中意味着什么
- c# - 为什么我不能使用他们提供的示例通过 mapbox api 创建一个有效的样式?