Skip to content

Commit

Permalink
better polar chart
Browse files Browse the repository at this point in the history
  • Loading branch information
dernasherbrezon committed Jan 25, 2024
1 parent dd7c9f8 commit 0fc9463
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 49 deletions.
226 changes: 226 additions & 0 deletions src/components/AzElChart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
<template>
<canvas :id="id" :width="width"></canvas>
</template>

<script>
import Chart from 'chart.js';
import { Radar } from 'vue-chartjs'
export default {
extends: Radar,
props: ['chartData', 'id', 'width'],
name: 'azelchart',
methods: {
renderChart (data, options) {
this.$data._chart = new Chart(
document.getElementById(this.id).getContext('2d'), {
type: 'AzElChart',
data: data,
options: options,
plugins: this.plugins
}
)
}
},
mounted () {
// copy/paste from radarConfig
var AzElScaleDefaultConfig = {
display: true,
// Boolean - Whether to animate scaling the chart from the centre
animate: false,
position: 'chartArea',
angleLines: {
display: true,
color: 'rgba(0,0,0,0.1)',
lineWidth: 1,
borderDash: [],
borderDashOffset: 0.0
},
gridLines: {
circular: true
},
// label settings
ticks: {
// Boolean - Show a backdrop to the scale label
showLabelBackdrop: true,
// String - The colour of the label backdrop
backdropColor: 'rgba(255,255,255,0.75)',
// Number - The backdrop padding above & below the label in pixels
backdropPaddingY: 2,
// Number - The backdrop padding to the side of the label in pixels
backdropPaddingX: 2
},
pointLabels: {
// Boolean - if true, show point labels
display: true,
// Number - Point label font size in pixels
fontSize: 10,
// Function - Used to convert point labels
callback: function(label) {
return label;
}
}
};
var AzElScale = Chart.scaleService.getScaleConstructor('radialLinear').extend({
getPointPositionForValue: function(index, value) {
console.log(value)
var me = this;
var scalingFactor = me.drawingArea / (me.max - me.min);
return {
y: scalingFactor * Math.cos(value.x * Math.PI / 180.0) * (value.y - 90) + me.yCenter,
x: scalingFactor * Math.sin(value.x * Math.PI / 180.0) * (90 - value.y) + me.xCenter
};
},
getDistanceFromCenterForValue: function(value) {
console.log("here: " + value);
//console.trace();
var me = this;
// Take into account half font size + the yPadding of the top value
var scalingFactor = me.drawingArea / (me.max - me.min);
if (me.options.ticks.reverse) {
return (me.max - value) * scalingFactor;
}
return (value - me.min) * scalingFactor;
}
});
Chart.scaleService.registerScaleType('AzElScale', AzElScale, AzElScaleDefaultConfig);
Chart.defaults.AzElChart = Chart.defaults.radar;
// copy-paste from radar.
// the only difference is:
// line._loop = false;
// this will make line instead of square
var AzElChart = Chart.controllers.radar.extend({
_setDatasetHoverStyle: function() {
var element = this.getMeta().dataset;
var prev = {};
var i, ilen, key, keys, hoverOptions, model;
if (!element) {
return;
}
model = element._model;
hoverOptions = this._resolveDatasetElementOptions(element, true);
keys = Object.keys(hoverOptions);
for (i = 0, ilen = keys.length; i < ilen; ++i) {
key = keys[i];
prev[key] = model[key];
model[key] = hoverOptions[key];
}
element.$previousStyle = prev;
console.log("here");
},
update: function(reset) {
var me = this;
var meta = me.getMeta();
var line = meta.dataset;
var points = meta.data || [];
var scale = me.chart.scale;
var config = me._config;
var i, ilen;
// Compatibility: If the properties are defined with only the old name, use those values
if (config.tension !== undefined && config.lineTension === undefined) {
config.lineTension = config.tension;
}
// Utility
line._scale = scale;
line._datasetIndex = me.index;
// Data
line._children = points;
line._loop = false;
// Model
line._model = me._resolveDatasetElementOptions(line);
line.pivot();
// Update Points
for (i = 0, ilen = points.length; i < ilen; ++i) {
me.updateElement(points[i], i, reset);
}
// Update bezier control points
me.updateBezierControlPoints();
// Now pivot the point for animation
for (i = 0, ilen = points.length; i < ilen; ++i) {
points[i].pivot();
}
}
});
Chart.controllers.AzElChart = AzElChart;
this.renderChart({
labels: ['0 (North)', '45', '90', '135', '180', '225', '270', '315'],
datasets: [{
label: 'Data',
data: this.chartData,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 2,
pointBackgroundColor: 'rgba(75, 192, 192, 1)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(75, 192, 192, 1)',
}]
}, {
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 4,
hoverBorderWidth: 3
},
line: {
tension: 0 // disables bezier curves
}
},
animation: {
duration: 0
},
scale: {
type: 'AzElScale',
angleLines: {
display: true
},
ticks: {
display: false
}
},
legend: {
display: false
},
tooltips: {
displayColors: false,
callbacks: {
title: function(tooltipItem, data) {
return data.datasets[tooltipItem[0].datasetIndex].data[tooltipItem[0].index].time;
},
label: function(tooltipItem, data) {
let item = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return [
"AZ: " + item.x,
"EL: " + item.y
];
}
}
}
})
}
}
</script>
59 changes: 10 additions & 49 deletions src/components/pages/observation/entity.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@
</pre>
</b-card-body>
</b-collapse>
</b-card>
</b-card>
</div>
</div>
</div>
</b-tab>
<b-tab title="Spectogram">
<div class="row" style="margin-top: 20px;" v-if="observation.spectogramURL && !generatingSpectogram">
Expand All @@ -119,27 +119,7 @@
<b-tab title="Polar Plot">
<div class="row" style="margin-top: 20px;" v-if="observation.tle">
<div class="col-md-12">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="polar" width="120px" height="120px" viewBox="-110 -110 220 220" overflow="hidden">
<path fill="none" stroke="black" stroke-width="1" d="M 0 -95 v 190 M -95 0 h 190"></path>
<circle fill="none" stroke="black" cx="0" cy="0" r="30"></circle>
<circle fill="none" stroke="black" cx="0" cy="0" r="60"></circle>
<circle fill="none" stroke="black" cx="0" cy="0" r="90"></circle>
<text x="-4" y="-96">
N
</text>
<text x="-4" y="105">
S
</text>
<text x="96" y="4">
E
</text>
<text x="-106" y="4">
W
</text>
<path fill="none" stroke="blue" stroke-opacity="1.0" stroke-width="3" :d="polarPlot.curve"></path>
<circle v-if="polarPlot.start" fill="lightgreen" stroke="black" stroke-width="1" :cx="polarPlot.start.x" :cy="polarPlot.start.y" r="7"></circle>
<circle v-if="polarPlot.end" fill="red" stroke="black" stroke-width="1" :cx="polarPlot.end.x" :cy="polarPlot.end.y" r="7"></circle>
</svg>
<azelchart id="radarChart" width="400" :chartData="chartData"></azelchart>
</div>
</div>
</b-tab>
Expand Down Expand Up @@ -195,24 +175,25 @@
</div>
<div class="col-md-12" style="text-align: center;" v-else="loading">
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
<span class="sr-only">Loading...</span>
</div>
</div>
</template>

<script>
import moment from 'moment'
import * as satellite from 'satellite.js'
import azelchart from '@/components/AzElChart.vue'
export default {
name: 'observationLoad',
components: {azelchart},
data () {
return {
observation: {},
loading: true,
generatingSpectogram: false,
polarPlot: {
}
chartData: []
}
},
mounted () {
Expand Down Expand Up @@ -262,31 +243,17 @@ export default {
},
generatePolarPlot(satrec) {
const vm = this
var g = ''
var observerGd = {
longitude: vm.observation.groundStation.lon * Math.PI / 180.0,
latitude: vm.observation.groundStation.lat * Math.PI / 180.0,
height: 0
}
var azelData = []
for (var t = moment(vm.observation.start); t < moment(vm.observation.end); t.add(20, 's')) {
var skyPosition = vm.polarGetAzEl(satrec, observerGd, t);
var coord = vm.polarGetXY(skyPosition.azimuth, skyPosition.elevation);
if (g === '') {
g += 'M'
} else {
g += ' L'
}
g += coord.x + ' ' + coord.y
}
var skyStart = vm.polarGetAzEl(satrec, observerGd, moment(vm.observation.start))
var coordStart = vm.polarGetXY(skyStart.azimuth, skyStart.elevation)
var skyEnd = vm.polarGetAzEl(satrec, observerGd, moment(vm.observation.end))
var coordEnd = vm.polarGetXY(skyEnd.azimuth, skyEnd.elevation)
vm.polarPlot = {
curve: g,
start: coordStart,
end: coordEnd
azelData.push({x: skyPosition.azimuth.toFixed(2), y: skyPosition.elevation.toFixed(2), time: t.utc().format('HH:mm:ss')})
}
vm.chartData = azelData
},
polarGetAzEl(satrec, observerGd, t) {
var positionAndVelocity = satellite.propagate(satrec, t.toDate())
Expand All @@ -300,12 +267,6 @@ export default {
return {'azimuth': lookAngles.azimuth * 180 / Math.PI,
'elevation': lookAngles.elevation * 180 / Math.PI}
},
polarGetXY(az, el) {
var ret = {};
ret.x = (90 - el) * Math.sin(az * Math.PI / 180.0);
ret.y = (el - 90) * Math.cos(az * Math.PI / 180.0);
return ret;
},
formatDate (unixTimestamp) {
if (unixTimestamp) {
return moment(unixTimestamp).utc().format('DD-MMM-YYYY')
Expand Down

0 comments on commit 0fc9463

Please sign in to comment.