mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
3 Commits
plot-impor
...
open1337
Author | SHA1 | Date | |
---|---|---|---|
9d9d1b1de2 | |||
311e221af5 | |||
6281b67e47 |
@ -92,7 +92,10 @@ define([
|
|||||||
"features": "creation",
|
"features": "creation",
|
||||||
"model": {
|
"model": {
|
||||||
"telemetry": {
|
"telemetry": {
|
||||||
"period": 10
|
"period": 10,
|
||||||
|
"amplitude": 1,
|
||||||
|
"offset": 0,
|
||||||
|
"dataRateInHz": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"telemetry": {
|
"telemetry": {
|
||||||
@ -135,6 +138,42 @@ define([
|
|||||||
"period"
|
"period"
|
||||||
],
|
],
|
||||||
"pattern": "^\\d*(\\.\\d*)?$"
|
"pattern": "^\\d*(\\.\\d*)?$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Amplitude",
|
||||||
|
"control": "textfield",
|
||||||
|
"cssclass": "l-input-sm l-numeric",
|
||||||
|
"key": "amplitude",
|
||||||
|
"required": true,
|
||||||
|
"property": [
|
||||||
|
"telemetry",
|
||||||
|
"amplitude"
|
||||||
|
],
|
||||||
|
"pattern": "^\\d*(\\.\\d*)?$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Offset",
|
||||||
|
"control": "textfield",
|
||||||
|
"cssclass": "l-input-sm l-numeric",
|
||||||
|
"key": "offset",
|
||||||
|
"required": true,
|
||||||
|
"property": [
|
||||||
|
"telemetry",
|
||||||
|
"offset"
|
||||||
|
],
|
||||||
|
"pattern": "^\\d*(\\.\\d*)?$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Data Rate (hz)",
|
||||||
|
"control": "textfield",
|
||||||
|
"cssclass": "l-input-sm l-numeric",
|
||||||
|
"key": "dataRateInHz",
|
||||||
|
"required": true,
|
||||||
|
"property": [
|
||||||
|
"telemetry",
|
||||||
|
"dataRateInHz"
|
||||||
|
],
|
||||||
|
"pattern": "^\\d*(\\.\\d*)?$"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
83
example/generator/src/GeneratorProvider.js
Normal file
83
example/generator/src/GeneratorProvider.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./WorkerInterface'
|
||||||
|
], function (
|
||||||
|
WorkerInterface
|
||||||
|
) {
|
||||||
|
|
||||||
|
var REQUEST_DEFAULTS = {
|
||||||
|
amplitude: 1,
|
||||||
|
period: 10,
|
||||||
|
offset: 0,
|
||||||
|
dataRateInHz: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
function GeneratorProvider() {
|
||||||
|
this.workerInterface = new WorkerInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneratorProvider.prototype.canProvideTelemetry = function (domainObject) {
|
||||||
|
return domainObject.type === 'generator';
|
||||||
|
};
|
||||||
|
|
||||||
|
GeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request) {
|
||||||
|
var props = [
|
||||||
|
'amplitude',
|
||||||
|
'period',
|
||||||
|
'offset',
|
||||||
|
'dataRateInHz'
|
||||||
|
];
|
||||||
|
|
||||||
|
var workerRequest = {};
|
||||||
|
|
||||||
|
props.forEach(function (prop) {
|
||||||
|
if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) {
|
||||||
|
workerRequest[prop] = domainObject.telemetry[prop];
|
||||||
|
}
|
||||||
|
if (request.hasOwnProperty(prop)) {
|
||||||
|
workerRequest[prop] = request[prop];
|
||||||
|
}
|
||||||
|
if (!workerRequest[prop]) {
|
||||||
|
workerRequest[prop] = REQUEST_DEFAULTS[prop];
|
||||||
|
}
|
||||||
|
workerRequest[prop] = Number(workerRequest[prop]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return workerRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
GeneratorProvider.prototype.request = function (domainObject, request) {
|
||||||
|
var workerRequest = this.makeWorkerRequest(domainObject, request);
|
||||||
|
workerRequest.start = request.start;
|
||||||
|
workerRequest.end = request.end;
|
||||||
|
return this.workerInterface.request(workerRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
GeneratorProvider.prototype.subscribe = function (domainObject, callback, request) {
|
||||||
|
var workerRequest = this.makeWorkerRequest(domainObject, request);
|
||||||
|
return this.workerInterface.subscribe(workerRequest, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
return GeneratorProvider;
|
||||||
|
});
|
@ -24,96 +24,47 @@
|
|||||||
/**
|
/**
|
||||||
* Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
* Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define([
|
||||||
["./SinewaveTelemetrySeries"],
|
"./SinewaveTelemetrySeries",
|
||||||
function (SinewaveTelemetrySeries) {
|
"./GeneratorProvider"
|
||||||
"use strict";
|
], function (
|
||||||
|
SinewaveTelemetrySeries,
|
||||||
|
GeneratorProvider
|
||||||
|
) {
|
||||||
|
|
||||||
/**
|
function SinewaveTelemetryProvider() {
|
||||||
*
|
this.provider = new GeneratorProvider();
|
||||||
* @constructor
|
}
|
||||||
*/
|
|
||||||
function SinewaveTelemetryProvider($q, $timeout) {
|
|
||||||
var subscriptions = [],
|
|
||||||
generating = false;
|
|
||||||
|
|
||||||
//
|
SinewaveTelemetryProvider.prototype.requestTelemetry = function (requests) {
|
||||||
function matchesSource(request) {
|
if (requests[0].source !== 'generator') {
|
||||||
return request.source === "generator";
|
return Promise.resolve({});
|
||||||
}
|
}
|
||||||
|
return this.provider.request({}, requests[0])
|
||||||
// Used internally; this will be repacked by doPackage
|
.then(function (data) {
|
||||||
function generateData(request) {
|
var res = {
|
||||||
return {
|
generator: {}
|
||||||
key: request.key,
|
|
||||||
telemetry: new SinewaveTelemetrySeries(request)
|
|
||||||
};
|
};
|
||||||
}
|
res.generator[requests[0].key] = new SinewaveTelemetrySeries(data);
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
//
|
SinewaveTelemetryProvider.prototype.subscribe = function (callback, requests) {
|
||||||
function doPackage(results) {
|
if (requests[0].source !== 'generator') {
|
||||||
var packaged = {};
|
return function unsubscribe() {};
|
||||||
results.forEach(function (result) {
|
|
||||||
packaged[result.key] = result.telemetry;
|
|
||||||
});
|
|
||||||
// Format as expected (sources -> keys -> telemetry)
|
|
||||||
return { generator: packaged };
|
|
||||||
}
|
|
||||||
|
|
||||||
function requestTelemetry(requests) {
|
|
||||||
return $timeout(function () {
|
|
||||||
return doPackage(requests.filter(matchesSource).map(generateData));
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSubscriptions() {
|
|
||||||
subscriptions.forEach(function (subscription) {
|
|
||||||
var requests = subscription.requests;
|
|
||||||
subscription.callback(doPackage(
|
|
||||||
requests.filter(matchesSource).map(generateData)
|
|
||||||
));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function startGenerating() {
|
|
||||||
generating = true;
|
|
||||||
$timeout(function () {
|
|
||||||
handleSubscriptions();
|
|
||||||
if (generating && subscriptions.length > 0) {
|
|
||||||
startGenerating();
|
|
||||||
} else {
|
|
||||||
generating = false;
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function subscribe(callback, requests) {
|
|
||||||
var subscription = {
|
|
||||||
callback: callback,
|
|
||||||
requests: requests
|
|
||||||
};
|
|
||||||
|
|
||||||
function unsubscribe() {
|
|
||||||
subscriptions = subscriptions.filter(function (s) {
|
|
||||||
return s !== subscription;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
subscriptions.push(subscription);
|
|
||||||
|
|
||||||
if (!generating) {
|
|
||||||
startGenerating();
|
|
||||||
}
|
|
||||||
|
|
||||||
return unsubscribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
requestTelemetry: requestTelemetry,
|
|
||||||
subscribe: subscribe
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SinewaveTelemetryProvider;
|
function wrapper(data) {
|
||||||
}
|
var res = {
|
||||||
);
|
generator: {}
|
||||||
|
};
|
||||||
|
res.generator[requests[0].key] = new SinewaveTelemetrySeries(data);
|
||||||
|
callback(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.provider.subscribe({}, wrapper, requests[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return SinewaveTelemetryProvider;
|
||||||
|
});
|
||||||
|
@ -24,55 +24,52 @@
|
|||||||
/**
|
/**
|
||||||
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
||||||
*/
|
*/
|
||||||
define(
|
define([
|
||||||
['./SinewaveConstants'],
|
|
||||||
function (SinewaveConstants) {
|
], function (
|
||||||
|
|
||||||
|
) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ONE_DAY = 60 * 60 * 24,
|
function SinewaveTelemetrySeries(data) {
|
||||||
firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000);
|
if (!Array.isArray(data)) {
|
||||||
|
data = [data];
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function SinewaveTelemetrySeries(request) {
|
|
||||||
var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0,
|
|
||||||
latestTime = Math.floor(Date.now() / 1000) - timeOffset,
|
|
||||||
firstTime = firstObservedTime - timeOffset,
|
|
||||||
endTime = (request.end !== undefined) ?
|
|
||||||
Math.floor(request.end / 1000) : latestTime,
|
|
||||||
count = Math.min(endTime, latestTime) - firstTime,
|
|
||||||
period = +request.period || 30,
|
|
||||||
generatorData = {},
|
|
||||||
requestStart = (request.start === undefined) ? firstTime :
|
|
||||||
Math.max(Math.floor(request.start / 1000), firstTime),
|
|
||||||
offset = requestStart - firstTime;
|
|
||||||
|
|
||||||
if (request.size !== undefined) {
|
|
||||||
offset = Math.max(offset, count - request.size);
|
|
||||||
}
|
}
|
||||||
|
this.data = data;
|
||||||
generatorData.getPointCount = function () {
|
|
||||||
return count - offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
generatorData.getDomainValue = function (i, domain) {
|
|
||||||
// delta uses the same numeric values as the default domain,
|
|
||||||
// so it's not checked for here, just formatted for display
|
|
||||||
// differently.
|
|
||||||
return (i + offset) * 1000 + firstTime * 1000 -
|
|
||||||
(domain === 'yesterday' ? (ONE_DAY * 1000) : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
generatorData.getRangeValue = function (i, range) {
|
|
||||||
range = range || "sin";
|
|
||||||
return Math[range]((i + offset) * Math.PI * 2 / period);
|
|
||||||
};
|
|
||||||
|
|
||||||
return generatorData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SinewaveTelemetrySeries.prototype.getPointCount = function () {
|
||||||
|
return this.data.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SinewaveTelemetrySeries.prototype.getDomainValue = function (
|
||||||
|
index,
|
||||||
|
domain
|
||||||
|
) {
|
||||||
|
domain = domain || 'time';
|
||||||
|
|
||||||
|
return this.getDatum(index)[domain];
|
||||||
|
};
|
||||||
|
|
||||||
|
SinewaveTelemetrySeries.prototype.getRangeValue = function (
|
||||||
|
index,
|
||||||
|
range
|
||||||
|
) {
|
||||||
|
range = range || 'sin';
|
||||||
|
return this.getDatum(index)[range];
|
||||||
|
};
|
||||||
|
|
||||||
|
SinewaveTelemetrySeries.prototype.getDatum = function (index) {
|
||||||
|
if (index > this.data.length || index < 0) {
|
||||||
|
throw new Error('IndexOutOfRange: index not available in series.');
|
||||||
|
}
|
||||||
|
return this.data[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
SinewaveTelemetrySeries.prototype.getData = function () {
|
||||||
|
return this.data;
|
||||||
|
};
|
||||||
|
|
||||||
return SinewaveTelemetrySeries;
|
return SinewaveTelemetrySeries;
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
115
example/generator/src/WorkerInterface.js
Normal file
115
example/generator/src/WorkerInterface.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'text!./generatorWorker.js',
|
||||||
|
'uuid'
|
||||||
|
], function (
|
||||||
|
workerText,
|
||||||
|
uuid
|
||||||
|
) {
|
||||||
|
|
||||||
|
var workerBlob = new Blob(
|
||||||
|
[workerText],
|
||||||
|
{type: 'application/javascript'}
|
||||||
|
);
|
||||||
|
var workerUrl = URL.createObjectURL(workerBlob);
|
||||||
|
|
||||||
|
function WorkerInterface() {
|
||||||
|
this.worker = new Worker(workerUrl);
|
||||||
|
this.worker.onmessage = this.onMessage.bind(this);
|
||||||
|
this.callbacks = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerInterface.prototype.onMessage = function (message) {
|
||||||
|
message = message.data;
|
||||||
|
var callback = this.callbacks[message.id];
|
||||||
|
if (callback) {
|
||||||
|
if (callback(message)) {
|
||||||
|
delete this.callbacks[message.id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
WorkerInterface.prototype.dispatch = function (request, data, callback) {
|
||||||
|
var message = {
|
||||||
|
request: request,
|
||||||
|
data: data,
|
||||||
|
id: uuid()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
this.callbacks[message.id] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.worker.postMessage(message);
|
||||||
|
|
||||||
|
return message.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
WorkerInterface.prototype.request = function (request) {
|
||||||
|
var deferred = {};
|
||||||
|
var promise = new Promise(function (resolve, reject) {
|
||||||
|
deferred.resolve = resolve;
|
||||||
|
deferred.reject = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
function callback(message) {
|
||||||
|
if (message.error) {
|
||||||
|
deferred.reject(message.error);
|
||||||
|
} else {
|
||||||
|
deferred.resolve(message.data);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatch('request', request, callback);
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
WorkerInterface.prototype.subscribe = function (request, cb) {
|
||||||
|
var isCancelled = false;
|
||||||
|
|
||||||
|
var callback = function (message) {
|
||||||
|
if (isCancelled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cb(message.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
var messageId = this.dispatch('subscribe', request, callback)
|
||||||
|
|
||||||
|
return function () {
|
||||||
|
isCancelled = true;
|
||||||
|
this.dispatch('unsubscribe', {
|
||||||
|
id: messageId
|
||||||
|
});
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return WorkerInterface;
|
||||||
|
});
|
150
example/generator/src/generatorWorker.js
Normal file
150
example/generator/src/generatorWorker.js
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*global self*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
|
||||||
|
var handlers = {
|
||||||
|
subscribe: onSubscribe,
|
||||||
|
unsubscribe: onUnsubscribe,
|
||||||
|
request: onRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
var subscriptions = {};
|
||||||
|
|
||||||
|
function workSubscriptions(timestamp) {
|
||||||
|
var now = Date.now();
|
||||||
|
var nextWork = Math.min.apply(Math, Object.values(subscriptions).map(function (subscription) {
|
||||||
|
return subscription(now);
|
||||||
|
}));
|
||||||
|
var wait = nextWork - now;
|
||||||
|
if (wait < 0) {
|
||||||
|
wait = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isFinite(wait)) {
|
||||||
|
setTimeout(workSubscriptions, wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubscribe(message) {
|
||||||
|
var data = message.data;
|
||||||
|
|
||||||
|
var start = Date.now();
|
||||||
|
var step = 1000 / data.dataRateInHz;
|
||||||
|
var nextStep = start - (start % step) + step;
|
||||||
|
|
||||||
|
function work(now) {
|
||||||
|
while (nextStep < now) {
|
||||||
|
self.postMessage({
|
||||||
|
id: message.id,
|
||||||
|
data: {
|
||||||
|
utc: nextStep,
|
||||||
|
yesterday: nextStep - 60*60*24*1000,
|
||||||
|
delta: 60*60*24*1000,
|
||||||
|
sin: sin(nextStep, data.period, data.amplitude, data.offset),
|
||||||
|
cos: cos(nextStep, data.period, data.amplitude, data.offset)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nextStep += step;
|
||||||
|
}
|
||||||
|
return nextStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriptions[message.id] = work;
|
||||||
|
workSubscriptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUnsubscribe(message) {
|
||||||
|
delete subscriptions[message.data.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
function onRequest(message) {
|
||||||
|
var data = message.data;
|
||||||
|
if (!data.start || !data.end) {
|
||||||
|
throw new Error('missing start and end!');
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = Date.now();
|
||||||
|
var start = data.start;
|
||||||
|
var end = data.end > now ? now : data.end;
|
||||||
|
var amplitude = data.amplitude;
|
||||||
|
var period = data.period;
|
||||||
|
var offset = data.offset;
|
||||||
|
var dataRateInHz = data.dataRateInHz;
|
||||||
|
|
||||||
|
var step = 1000 / dataRateInHz;
|
||||||
|
var nextStep = start - (start % step) + step;
|
||||||
|
|
||||||
|
var data = [];
|
||||||
|
|
||||||
|
for (; nextStep < end; nextStep += step) {
|
||||||
|
data.push({
|
||||||
|
utc: nextStep,
|
||||||
|
yesterday: nextStep - 60*60*24*1000,
|
||||||
|
delta: 60*60*24*1000,
|
||||||
|
sin: sin(nextStep, period, amplitude, offset),
|
||||||
|
cos: cos(nextStep, period, amplitude, offset)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.postMessage({
|
||||||
|
id: message.id,
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cos(timestamp, period, amplitude, offset) {
|
||||||
|
return amplitude *
|
||||||
|
Math.cos(timestamp / period / 1000 * Math.PI * 2) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sin(timestamp, period, amplitude, offset) {
|
||||||
|
return amplitude *
|
||||||
|
Math.sin(timestamp / period / 1000 * Math.PI * 2) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendError(error, message) {
|
||||||
|
self.postMessage({
|
||||||
|
error: error.name + ': ' + error.message,
|
||||||
|
message: message,
|
||||||
|
id: message.id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onmessage = function handleMessage(event) {
|
||||||
|
var message = event.data;
|
||||||
|
var handler = handlers[message.request];
|
||||||
|
|
||||||
|
if (!handler) {
|
||||||
|
sendError(new Error('unknown message type'), message);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
handler(message);
|
||||||
|
} catch (e) {
|
||||||
|
sendError(e, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
Reference in New Issue
Block a user