let all_dataView = new MyDataView();
await all_dataView.init(
{
start: startDate,
end: endDate,
},
RESOLUTION
);
let extensions = [];
/**
The 'onTimeRangeChanged' function is defined to handle changes in the time range.
When the time range changes, it triggers the 'refresh' method of 'dataView'
to update the data within the specified time frame. After refreshing 'dataView',
it associates any registered extensions with it.
@param {Date} startDate - The start date for data retrieval.
@param {Date} endDate - The end date for data retrieval.
@param {number} RESOLUTION - The resolution for data retrieval.
*/
async function onTimeRangeChanged(start, end, RESOLUTION) {
await dataView.refresh({ start, end }, RESOLUTION);
extensions.forEach((ext) => (ext.dataView = dataView));
}
/**
The 'onTimeMarkerChanged' function is designed to respond to changes in a time marker.
It iterates through all registered extensions and updates their 'currentTime' property
to synchronize them with the new time marker value.
@param {Date} time - The new time marker value.
*/
function onTimeMarkerChanged(time) {
extensions.forEach((ext) => (ext.currentTime = time));
}
function onCurrentChannelChanged(channelId) {
extensions.forEach((ext) => (ext.currentChannelID = channelId));
}
/**
This function, 'onCurrentSensorChanged', is triggered when the current sensor is changed.
It performs the following actions:
Sets up and auto-activates IoT extensions by iterating through 'IOT_EXTENSION_IDS'.
Retrieves the sensor's description from 'all_dataView'.
Creates a mapping of sensor descriptions to their corresponding channels.
Updates the '_channels' property of 'dataView' with the created mapping.
Associates each IoT extension with 'dataView'.
Clears the 'currentSensorID' property of each extension.
Fits the viewer's view to the sensor's object if it exists.
Sets the 'currentSensorID' property for each extension to the new sensor ID.
@param {string} sensorId - The ID of the current sensor.
*/
function onCurrentSensorChanged(sensorId) {
// Setup and auto-activate IoT extensions
extensions = [];
for (const extensionID of IOT_EXTENSION_IDS) {
const extension = viewer.getExtension(extensionID);
onTimeRangeChanged(startDate, endDate, RESOLUTION);
}
async function onModelSelected(typeOfsensor) {
extensions = [];
// Setup and auto-activate IoT extensions
for (const extensionID of IOT_EXTENSION_IDS) {
const extension = viewer.getExtension(extensionID);
extensions.push(extension);
var test2 = all_dataView.getSensors();
var sensorMap = new Map();
var myMap = new Map();
let all_channels = Array.from(all_dataView.getChannels().keys());
let channelNames = all_channels.filter(function (channel) {
return channel.startsWith(typeOfsensor);
});
for (var channelName of channelNames) {
var channels = all_dataView.getChannels().get(channelName);
myMap.set(channelName, channels);
}
test2.forEach((sensor) => {
if (channelNames.includes(sensor.description)) {
sensorMap.set(sensor.code, sensor);
}
});
dataView._channels = myMap;
dataView._sensorsFilteredByFloor = sensorMap;
extension.dataView = dataView;
extension.activate();
if (IOT_PANEL_STYLES[extensionID]) {
adjustPanelStyle(extension.panel, IOT_PANEL_STYLES[extensionID]);
}
}
}
async function setupModelSelection(typeSensors, selectedUrn) {
const dropdown = document.getElementById("models");
try {
dropdown.innerHTML = typeSensors
.map(
(model) =>
<option value=${model} ${ model === selectedUrn ? "selected" : "" }>${model}</option>
)
.join("\n");
// ajouter du style au dropdown
dropdown.classList.add("custom-dropdown");
dropdown.onchange = () => {
onModelSelected(dropdown.value);
};
} catch (err) {
alert("Could not list models. See the console for more details.");
console.error(err);
}
}
function getSpritesPositions() {
return new Promise((resolve, reject) => {
fetch("/getDbids")
.then((response) => {
if (!response.ok) {
throw new Error("Réponse du serveur non valide");
}
return response.json();
})
.then((dbids) => {
// Traiter les dbids reçus depuis le backend
dbids = dbids.map((dbid) => parseInt(dbid, 10));
// get dbids of the viewer
var fragIds = viewer.model.getData().instanceTree;
// dbIds is all the dbis of all the objects in the viewer
var dbIds = Object.keys(fragIds.nodeAccess.dbIdToIndex);
var copy_dbIds_selected = [
1233,2345?3456,245
];
const tree = viewer.model.getInstanceTree();
const frags = viewer.model.getFragmentList();
let test2 = [];
if (tree) {
dbids.map((dbId) => {
var fragIds = [];
tree.enumNodeFragments(
dbId,
(fragId) => {
fragIds.push(fragId);
},
false
);
let matrix = new THREE.Matrix4();
frags.getWorldMatrix(fragIds, matrix);
let bbox = new THREE.Box3();
frags.getWorldBounds(fragIds[0], bbox);
const x = (bbox.max.x + bbox.min.x) / 2;
const y = (bbox.max.y + bbox.min.y) / 2;
const z = (bbox.max.z + bbox.min.z) / 2;
test2.push({
id: dbId,
code: "1",
name: "",
description: "",
groupName: "",
location: {
x: x,
y: y,
z: z,
},
objectId: dbId,
});
});
}
resolve(test2); // Résoudre la promesse avec les données
})
.catch((error) => {
console.error("Erreur lors de la récupération des dbids :", error);
reject(error); // Rejeter la promesse en cas d'erreur
});
});
}
var FORGE_MODEL_URN;
fetch("/api/config")
.then((response) => response.json())
.then((data) => {
FORGE_MODEL_URN = data.apiKey;
loadModel(viewer, FORGE_MODEL_URN, FORGE_MODEL_VIEW);
})
.catch((error) => {
console.error("Erreur lors de la récupération des données :", error);
});
viewer.addEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
async function (timeSlider) {
var typeSensors = [];
const sensors = dataView.getSensors();
sensors.forEach((sensor) => {
if (!typeSensors.includes(sensor.description)) {
typeSensors.push(sensor.description);
}
});
Here is the code of the file where I declared these 2 lines timeSlider.mStartTime = start;
timeSlider.mEndTime = end; but I don't understand why it still doesn't trigger tsmodified
if you have an idea why this is happening please tell me how to fix it
You can adjust the time range of the slider using the timeline.zoomTo(startDateString, endDateString) method. I've created an experiment/time-select branch that demonstrates the use of this feature.
import { initViewer, loadModel, adjustPanelStyle } from "./viewer.js"; import { initTimeline } from "./timeline.js"; import { MyDataView } from "./dataview.js"; import "./sensormanager.js";
const FORGE_MODEL_VIEW = ""; const RESOLUTION = 15;
const IOT_EXTENSION_IDS = [ "IoT.SensorList", "IoT.SensorDetail", "IoT.SensorSprites", "IoT.DataGrid", "IoT.SensorHeatmaps", ];
const IOT_PANEL_STYLES = { "IoT.SensorList": { right: "10px", top: "50px", width: "700px", height: "auto", // resize: "both", // marginBottom: "0em", }, "IoT.SensorHeatmaps": { left: "10px", top: "320px", width: "300px", height: "150px", }, };
const currentDate = new Date(); currentDate.setUTCHours(0, 0, 0, 0);
var endDate = new Date(currentDate.getTime()); endDate.setUTCHours(0, 0, 0, 0);
var startDate = new Date(currentDate.getTime() - 3 24 60 60 1000); startDate.setUTCHours(0, 0, 0, 0);
const timeSlider = await initTimeline( document.getElementById("timeline"), onTimeRangeChanged, onTimeMarkerChanged, startDate, endDate ); timeSlider.mStartTime = startDate; timeSlider.mEndTime = endDate; let dataView = new MyDataView(); await dataView.init( { start: startDate, end: endDate, }, RESOLUTION );
let all_dataView = new MyDataView(); await all_dataView.init( { start: startDate, end: endDate, }, RESOLUTION );
let extensions = [];
/**
async function onTimeRangeChanged(start, end, RESOLUTION) { await dataView.refresh({ start, end }, RESOLUTION); extensions.forEach((ext) => (ext.dataView = dataView)); }
/**
function onTimeMarkerChanged(time) { extensions.forEach((ext) => (ext.currentTime = time)); }
function onCurrentChannelChanged(channelId) { extensions.forEach((ext) => (ext.currentChannelID = channelId)); }
/**
@param {string} sensorId - The ID of the current sensor. */ function onCurrentSensorChanged(sensorId) { // Setup and auto-activate IoT extensions extensions = []; for (const extensionID of IOT_EXTENSION_IDS) { const extension = viewer.getExtension(extensionID);
extensions.push(extension);
extension.dataView = dataView; extension.activate(); }
extensions.forEach((ext) => { ext.dataView = dataView;
ext.currentSensorID = null; }); const sensor = dataView.getSensors().get(sensorId);
if (sensor && sensor.objectId) { viewer.fitToView([sensor.objectId]); } extensions.forEach((ext) => (ext.currentSensorID = sensorId)); }
const viewer = await initViewer( document.getElementById("preview"), IOT_EXTENSION_IDS.concat(["Iot.SensorManager"]) );
async function handleDateSelect_start(start, RESOLUTION) { timeSlider.mStartTime = start.dateSelected;
startDate = start.dateSelected;
onTimeRangeChanged(startDate, endDate, RESOLUTION); } async function handleDateSelect_end(end, RESOLUTION) { timeSlider.mEndTime = end.dateSelected; timelineTest.end = end.dateSelected; endDate = end.dateSelected;
onTimeRangeChanged(startDate, endDate, RESOLUTION); } async function onModelSelected(typeOfsensor) { extensions = []; // Setup and auto-activate IoT extensions for (const extensionID of IOT_EXTENSION_IDS) { const extension = viewer.getExtension(extensionID); extensions.push(extension); var test2 = all_dataView.getSensors(); var sensorMap = new Map(); var myMap = new Map(); let all_channels = Array.from(all_dataView.getChannels().keys());
} } async function setupModelSelection(typeSensors, selectedUrn) { const dropdown = document.getElementById("models"); try { dropdown.innerHTML = typeSensors .map( (model) =>
<option value=${model} ${ model === selectedUrn ? "selected" : "" }>${model}</option>
) .join("\n"); // ajouter du style au dropdown dropdown.classList.add("custom-dropdown"); dropdown.onchange = () => { onModelSelected(dropdown.value); }; } catch (err) { alert("Could not list models. See the console for more details."); console.error(err); } } function getSpritesPositions() { return new Promise((resolve, reject) => { fetch("/getDbids") .then((response) => { if (!response.ok) { throw new Error("Réponse du serveur non valide"); }}); }
var FORGE_MODEL_URN;
fetch("/api/config") .then((response) => response.json()) .then((data) => { FORGE_MODEL_URN = data.apiKey; loadModel(viewer, FORGE_MODEL_URN, FORGE_MODEL_VIEW); }) .catch((error) => { console.error("Erreur lors de la récupération des données :", error); });
viewer.addEventListener( Autodesk.Viewing.GEOMETRY_LOADED_EVENT, async function (timeSlider) { var typeSensors = []; const sensors = dataView.getSensors(); sensors.forEach((sensor) => { if (!typeSensors.includes(sensor.description)) { typeSensors.push(sensor.description); } });
} );
Here is the code of the file where I declared these 2 lines timeSlider.mStartTime = start; timeSlider.mEndTime = end; but I don't understand why it still doesn't trigger tsmodified if you have an idea why this is happening please tell me how to fix it
Originally posted by @amelnait in https://github.com/autodesk-platform-services/aps-iot-extensions-demo/issues/13#issuecomment-1774792704