Error while call multiple animated sprite - autodesk-forge

Here I created several classes for each sprite. Examples are DeviceOne and DeviceTwo. All went well when only creating and loading 1 sprite. However when I call DeviceTwo and reload dataVizExtension I always get the following error.
Uncaught TypeError: Cannot read properties of undefined (reading 'dbId')
This is the code for DeviceOne, basically class for DeviceTwo is same. The different only the sprite images.
export class DeviceOne {
constructor(viewer, dataVizExtn) {
this.viewer = viewer;
this.dataVizExtn = null;
this.DataVizCore = null;
this.viewableType = null;
this.viewableData = null;
this.baseURL = "http://localhost:3000/assets/images/sprite/";
this.sensorPositions = {
Dasloop: {
x: 10,
y: -3,
z: 20,
},
Warning: {
x: 0,
y: 10,
z: 3,
},
};
this.dasloops = [
"img_gps_dasloop_online.svg",
"img_gps_dasloop_online-1.svg",
"img_gps_dasloop_online-2.svg",
"img_gps_dasloop_online-3.svg",
];
this.warnings = ["ic_warning.svg", "ic_warning-2.svg"];
this.startAnim1 = 0;
this.startAnim2 = 0;
this.startAnim3 = 0;
this.infoChart = new InfoChart(this.viewer, this.options);
}
/**
* #return {ViewableData} resulting viable data that contains all viewables (icons)
*/
async onSpriteLoadedToScene() {
this.dataVizExtn = await this.viewer.loadExtension(
"Autodesk.DataVisualization"
);
const dataVizCore = Autodesk.DataVisualization.Core;
this.onSpriteHovering = this.onSpriteHovering.bind(this);
this.viewer.addEventListener(
dataVizCore.MOUSE_HOVERING,
this.onSpriteHovering
);
this.onSpriteClicked = this.onSpriteClicked.bind(this);
this.viewer.addEventListener(dataVizCore.MOUSE_CLICK, this.onSpriteClicked);
const viewableType = dataVizCore.ViewableType.SPRITE;
const spriteColor = new THREE.Color(0xffffff);
const highlightedColor = new THREE.Color(0xe0e0ff);
const spriteIconUrl = `${this.baseURL}${"img_gps_dasloop_online.svg"}`;
const dasloopStyles = new dataVizCore.ViewableStyle(
viewableType,
spriteColor,
spriteIconUrl,
highlightedColor,
`${this.baseURL}${this.dasloops[0]}`,
this.dasloops.map((dasloop) => `${this.baseURL}${dasloop}`)
);
const warningStyles = new dataVizCore.ViewableStyle(
viewableType,
spriteColor,
`${this.baseURL}${"ic_warning.svg"}`,
highlightedColor,
`${this.baseURL}${this.warnings[0]}`,
this.warnings.map((warning) => `${this.baseURL}${warning}`)
);
this.viewableData = new dataVizCore.ViewableData();
this.viewableData.spriteSize = 30;
const simulationData = [
{ position: { x: 0, y: 0, z: 10 } },
{ position: { x: 5, y: -3, z: 10 } },
];
const warningData = [{ position: { x: 0, y: 0, z: 0 } }];
simulationData.forEach((myData, index) => {
const dbId = 10 + index;
const position = myData.position;
const viewable = new dataVizCore.SpriteViewable(
position,
dasloopStyles,
dbId
);
this.viewableData.addViewable(viewable);
});
warningData.forEach((myData, index) => {
const dbId = 15 + index;
const position = myData.position;
const viewableWarning = new dataVizCore.SpriteViewable(
position,
warningStyles,
dbId
);
this.viewableData.addViewable(viewableWarning);
});
await this.viewableData.finish();
this.dataVizExtn.addViewables(this.viewableData);
this.spriteToUpdate = this.dataVizExtn.viewableData.viewables.map(
(sprite) => sprite.dbId
);
this.animate = setInterval(this.getAnimateSprite.bind(this), 500);
}
getAnimateSprite() {
this.dataVizExtn.invalidateViewables(this.spriteToUpdate, (viewable) => {
switch (viewable.dbId) {
case 10:
return {
url: `${this.baseURL}${
this.dasloops[this.startAnim1++ % this.dasloops.length]
}`,
};
case 15:
return {
url: `${this.baseURL}${
this.warnings[this.startAnim2++ % this.warnings.length]
}`,
};
case 11:
return {
url: `${this.baseURL}${
this.dasloops[this.startAnim3++ % this.dasloops.length]
}`,
};
default:
break;
}
});
}

Sorry, it's a little hard for me to tell where the error came from with the above code snippet, but you mentioned reload dataVizExtension. So, I would advise you to check your this.animate = setInterval(this.getAnimateSprite.bind(this), 500);.
Did you clear the setInterval call by clearInterval(this.animate) while unloading and before reloading your extension?

Related

How to get xyz cordinates of forge-viewer onClick event?

I am following this (https://stackblitz.com/edit/angular-forge-viewer-pjyarf?file=app%2Fapp.component.ts) link to get the xyz cordinates of viewer onclick event in Angular.I cant get the viewer properly. Please help to get the solution.
ngOnInit() {
this.mainFunction();
}
mainFunction(){
this.viewerOptions = {
initializerOptions: {
env: 'AutodeskProduction',
getAccessToken: (
onGetAccessToken: (token: string, expire: number) => void
) => {
const expireTimeSeconds = 60 * 30;
onGetAccessToken(ACCESS_TOKEN, expireTimeSeconds);
},
api: 'derivativeV2',
enableMemoryManagement: true,
},
onViewerInitialized: (args: ViewerInitializedEvent) => {
args.viewerComponent.DocumentId = DOCUMENT_URN;
this.viewer=args.viewer;
},
};
}
selectionChanged(e){
const state = this.viewer.viewerState.getState({ viewport: true });
const globalOffset = this.viewer.model.myData.globalOffset
const currentPosition = new THREE.Vector3().fromArray( state.viewport.eye );
const originPosition = currentPosition.clone().add( globalOffset );
console.log("hiiihhaaaaaa:",originPosition);
}

ProducerStream producing only to single partition

I am trying to produce some messages to a single topic having 2 partitions. All the messages are going to partition number 2 only.
I would expect that a producer stream would distribute the messages across all partitions.
const kafka = require('kafka-node')
const { Transform } = require('stream');
const _ = require('lodash');
const client = new kafka.KafkaClient({ kafkaHost: 'localhost:9092' })
, streamproducer = new kafka.ProducerStream({kafkaClient: client});
const stdinTransform = new Transform({
objectMode: true,
decodeStrings: true,
transform (text, encoding, callback) {
let num = parseInt(text);
let message = { num: num, method: 'two' }
console.log('pushing message')
callback(null, {
topic: 'topic356',
messages: JSON.stringify(message)
});
}
});
stdinTransform.pipe(streamproducer);
function send() {
var message = new Date().toString();
stdinTransform.write([{ messages: [message] }]);
}
setInterval(send, 100);
ConsumerGroup:
var consumerOptions = {
kafkaHost: '127.0.0.1:9092',
groupId: 'ExampleTestGroup',
sessionTimeout: 15000,
protocol: ['roundrobin'],
fromOffset: 'latest' // equivalent of auto.offset.reset valid values are 'none', 'latest', 'earliest'
};
var topics = 'topic356';
var consumerGroup = new ConsumerGroup(Object.assign({ id: 'consumer1' }, consumerOptions), topics);
consumerGroup.on('data', onMessage);
var consumerGroup2 = new ConsumerGroup(Object.assign({ id: 'consumer2' }, consumerOptions), topics);
consumerGroup2.on('data', onMessage);
consumerGroup2.on('connect', function () {
setTimeout(function () {
consumerGroup2.close(true, function (error) {
console.log('consumer2 closed', error);
});
}, 25000);
});
function onMessage (message) {
console.log(
` partition: ${message.partition} `
);
}
Do you produce messages with a key? In Kafka, messages with the same key are published to the same partition.
use partitionerType in options, the default is 0,
Partitioner type (default = 0, random = 1, cyclic = 2, keyed = 3, custom = 4), default 0
new kafka.Producer(new kafka.KafkaClient({ kafkaHost: 'localhost:9092' }),{
partitionerType:1
});
https://github.com/SOHU-Co/kafka-node/issues/1094

Loss and mean squared error values not showing during training performance. Not getting predicted line

Currently we are trying to input uber data that includes time of day and ride fare into our TensorFlow.js model. We noticed that when we ran the model on the browser, the points are showing up on our scatterplot but during the training the loss and mean squared error values are not showing up and most importantly our model is not displaying a prediction line.
var userData = [
{
"City": "San Francisco",
"Product_Type": "UberEATS Marketplace",
"Trip_or_Order_Status": "COMPLETED",
"Request_Time": "2019-06-16 04:10:44 +0000 UTC",
"Begin_Trip_Time": "2019-06-16 04:44:40 +0000 UTC",
"Begin_Trip_Lat": "37.7352602",
"Begin_Trip_Lng": "-122.4203465",
"Begin_Trip_Address": "",
"Dropoff_Time": "2019-06-16 04:44:40 +0000 UTC",
"Dropoff_Lat": "37.7352602",
"Dropoff_Lng": "-122.4203465",
"Dropoff_Address": "",
"Distance_miles": "2.04",
"Fare_Amount": "32.34",
"Fare_Currency": "USD"
}...]
async function getData() {
const carsData = await userData;
// Here we map out the values for each car and filter out the list item that do not have an day or a pay value
const cleaned = carsData.map(car => ({
timeInMinutes: calculateMins(car.Request_Time),
pay_rate: normalizeUberPrice(car.Distance_miles, car.Fare_Amount),
}))
.filter(car => (car.day != null && car.pay != null));
return cleaned;
}
async function run() {
const data = await getData();
const values = data.map(d => ({
x: d.day,
y: d.pay,
}));
tfvis.render.scatterplot(
{ name: 'Horsepower v MPG' },
{ values },
{
xAxisDomain: [0, 1600],
yAxisDomain: [0,10],
xLabel: 'Day',
yLabel: 'Pay',
height: 300
}
);
const model = createModel();
tfvis.show.modelSummary({ name: 'Model Summary' }, model);
// Convert the data to a form we can use for training.
const tensorData = convertToTensor(data);
console.log(tensorData)
const { inputs, labels } = tensorData;
// Train the model
await trainModel(model, inputs, labels);
console.log('Done Training');
testModel(model, data, tensorData);
}
function createModel() {
const model = tf.sequential();
model.add(tf.layers.dense({ inputShape: [1], units: 25, useBias: true }));
model.add(tf.layers.dense({ units: 50, activation: "sigmoid" }));
model.add(tf.layers.dense({ units: 1, useBias: true }));
return model;
}
function convertToTensor(data) {
return tf.tidy(() => {
tf.util.shuffle(data);
const inputs = data.map(d => d.pay)
const labels = data.map(d => d.day);
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
//Step 3. Normalize the data to the range 0 - 1 using min-max scaling
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = labelTensor.max();
const labelMin = labelTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
// Return the min/max bounds so we can use them later.
inputMax,
inputMin,
labelMax,
labelMin,
}
});
}
async function trainModel(model, inputs, labels) {
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse'],
});
const batchSize = 32;
const epochs = 30;
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{
xAxisDomain: [0, 100],
yAxisDomain: [0,1],
height: 200,
callbacks: ['onEpochEnd'] }
// ',onBatchEnd'
),
history: tfvis.show.history({
name: 'History'},
history,
["loss","mse"])
});
}
function testModel(model, inputData, normalizationData) {
const { inputMax, inputMin, labelMin, labelMax } = normalizationData;
const [xs, preds] = tf.tidy(() => {
const xs = tf.linspace(0, 1, 100);
const preds = model.predict(xs.reshape([100, 1]));
const unNormXs = xs
.mul(inputMax.sub(inputMin))
.add(inputMin);
const unNormPreds = preds
.mul(labelMax.sub(labelMin))
.add(labelMin);
return [unNormXs.dataSync(), unNormPreds.dataSync()];
});
const predictedPoints = Array.from(xs).map((val, i) => {
return { x: val, y: preds[i] }
});
const originalPoints = inputData.map(d => ({
x: d.pay, y: d.day,
}));
console.log("ORIGINAL POINTS:")
console.log(originalPoints)
tfvis.render.scatterplot(
{ name: 'Model Predictions vs Original Data' },
{ values: [originalPoints, predictedPoints], series: ['original', 'predicted'] },
{
xAxisDomain: [0,10],
yAxisDomain: [0,1600],
xLabel: 'Horsepower',
yLabel: 'MPG',
height: 1000
}
);
}
document.addEventListener('DOMContentLoaded', run);
Basically we want to see a predicted line for our data but were not getting anything back.
It worked when we used data like this:
var userData = [{
day: 1
pay: 20
},...]
The data processing is not well performed. Thus, the values used for prediction contain NaN and Infinity. As a result, the error computed by model.fit is NaN and could therefore not be displayed on the chart of tfjs-vis.
The filtering
.filter(car => (car.day != null && car.pay != null));
is not removing NaN and Infinity. Instead, this condition can be used:
.filter(car => isFinite(car.pay + car.day) && !isNaN(car.pay + car.day));
Though, the NaN and Infinity are found within the values of car.day, here a general filtering is made over car.pay and car.day - thus the additional operation - to make sure that these values will not appear anywhere in the cleaned data.
here you can see how to display the loss.

Is the Property Database being Updated when Multiple Models are Loaded in The Same Viewer?

I managed to load multiple models into the same viewer and now I am trying to extract properties and values of the elements of each model; however, when I use getPropertyDb() and executeUserFunction(), I get back only the properties of the initial model.
I started with the code from this repo and used this article to understand how to load multiple models.
First model is loaded after a redirect from the server.
function onDocumentLoadSuccess(doc) {
const geometries = doc.getRoot().search({ type: 'geometry' });
if (geometries.length === 0) {
console.error('Document contains no viewables.');
return;
}
const initViewable = geometries[0];
const svfUrl = doc.getViewablePath(initViewable);
const mat = new THREE.Matrix4();
const modelOptions = {
placementTransform: mat,
globalOffset: { x: 0, y: 0, z: 0 },
sharedPropertyDbPath: doc.getPropertyDbPath()
};
const viewerDiv = document.getElementById('MyViewerDiv');
const config = {
extensions: myExtensions
};
viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv, config);
viewer.start(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
}
After the geometry of each model is loaded an extension does some stuff.
function MyExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
MyExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
MyExtension.prototype.constructor = MyExtension;
MyExtension.prototype.onGeometryLoadEvent = function(event) {
const myPromise = this.viewer.model
.getPropertyDb()
.executeUserFunction(userFunction);
myPromise
.then(function(retValue) {
if (!retValue) {
console.log('Model doesn\'t contain valid elemens.');
}
// do stuff...
})
.catch(err => console.log(err));
};
MyExtension.prototype.load = function() {
this.onGeometryLoadBinded = this.onGeometryLoadEvent.bind(this);
this.viewer.addEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
this.onGeometryLoadBinded
);
return true;
};
MyExtension.prototype.unload = function() {
this.viewer.removeEventListener(
Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
this.onGeometryLoadBinded
);
this.onGeometryLoadBinded = null;
return true;
};
Autodesk.Viewing.theExtensionManager.registerExtension(
'MyExtension',
MyExtension
);
function userFunction(pdb) {
// get properties of the elements
}
New models are loaded in the same viewer using an extension as well.
MyOtherExtension.prototype.onDocumentLoadSuccess = function(doc) {
// get the svfUrl of the initial geometry and set the loading options
this.viewer.loadModel(
svfUrl,
loaderOptions,
this.onLoadModelSuccessBinded,
this.onLoadModelErrorBinded
);
};
How do I update the Property Database in order to get the properties and values for all the models that are currently loaded into the viewer?
Try access a specific database through the model object:
viewer.impl.modelQueue().getModels()[index].getPropertyDb()

g rendered ouside of svg in d3.js implemented in angular 4

When i try to generate a word cloud using d3,js, the g element is rendered ouside of svg when i give data to it via api call. But when i supply data locally, it is working properly.The angular ts code is below:
import { Component, OnInit } from '#angular/core';
import * as D3 from 'd3';
import { PopulatTopicsService } from '../services/populat-topics.service';
declare let d3: any;
#Component({
selector: 'app-populat-topics',
templateUrl: './populat-topics.component.html',
styleUrls: ['./populat-topics.component.css']
})
export class PopulatTopicsComponent implements OnInit {
constructor(private popularService : PopulatTopicsService){}
//local data- works fine
// data = [
// {text: 'Bob',size:33,cuscolor: '#abaaea'},
// {text: 'Robin',size:12,cuscolor: '#abaaea'},
// {text: 'Anne',size:41,cuscolor: '#abaaea'},
// {text: 'Mark',size:16,cuscolor: '#abaaea'},
// {text: 'Joe',size:39,cuscolor: '#abaaea'}
// ];
network ="FB";
startDate ="01/04/2018";
endDate ="07/04/2018";
brandId ="720";
userId ="20615";
period ="LASTWEEK";
data =[];
wdata = "u gh h xfg fg gf";
ngOnInit() {
this.popularService.wordCloud(this.userId,this.startDate,this.endDate,this.brandId,this.period,this.network).subscribe(res =>
{
console.log(res);
this.data = res;
console.log(this.data['term']);
let cls = this;
// this.data = this.wdata.split(' ').map(function(d) {
// return {text: d, size: cls.getRandom()};
// });
this.setup();
this.buildSVG();
this.populate();
}
);
}
// data = [{'number':1},{'number':2}];
private svg; // SVG in which we will print our chart
private margin: { // Space between the svg borders and the actual chart graphic
top: number,
right: number,
bottom: number,
left: number
};
private width: number; // Component width
private height: number; // Component height
private fillScale; // D3 scale for text color
tempData = [];
private getRandom() {
let cls = this;
let size = 10 + Math.random() * 100;
if(size > 70 && this.tempData.length <= 10) {
this.tempData.push(size);
}
if(this.tempData.length > 10 && size > 14) {
return 12;
}
return size;
}
private setup() {
this.margin = {
top : 10,
right : 10,
bottom: 10,
left : 10
};
this.width = 1200;
this.height = 450;
let minFontSize: number = 18 ;
let maxFontSize: number = 96 ;
this.fillScale = D3.scaleOrdinal(D3.schemeCategory10);
// this.fillScale = ['#abaaea','#abaaea','#abaaea','#abaaea','#abaaea'];
}
private buildSVG() {
this.svg = D3.select("#wordCloud")
.append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + ~~(this.width / 2) + ',' + ~~(this.height / 2) + ')');
}
private populate() {
let fontFace: string = 'Roboto';
let fontWeight: string = 'normal';
let spiralType: string = 'archimedean';
d3.layout.cloud()
.size([this.width, this.height])
.words(this.data)
.padding(0)
.rotate(() => (~~(Math.random() * 2) * 0))
.font(fontFace)
.fontWeight(fontWeight)
.fontSize(d => (d.size))
.spiral(spiralType)
.on('end', () => {
this.drawWordCloud(this.data);
})
.start();
}
private drawWordCloud(words) {
this.svg
.selectAll('text')
.data(words)
.enter()
.append('text')
.style('font-size', d => 20 + 'px')
.style('fill', this.fillScale)
.attr('text-anchor', 'middle')
.attr('transform', d => 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')')
.attr('class', 'word-cloud')
.text(d => {
return d.term;
});
}
}
MY HTML IS GIVEN BELOW:
<div class ="tag_cloud-wrap" id ="wordCloud" ></div>
MY CSS:
.tag_cloud-wrap {
clear: both;
margin: 40px;
text-align: center;
}
JSON DATA obtained throug api call is:
0
:
{term: "#NYIAS", score: "-Infinity", normalizedScore: 0, totalTermFreq: 2, totalDocFreq: 2, …}
1
:
{term: "TORQUE", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
2
:
{term: "RS", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
3
:
{term: "SPORTBACK", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
4
:
{term: "COLOR", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
I am assigning term as text to word cloud.
Thanks in advance.