I have been working on a project for a few months now and my main issue i am having right now is appending to an xml file. I can create the files no problem. But i want to be able to add more data. Basically use it like a small database.
The code included is only a small part of the whole program but i believe it is in here i need help with to figure out the process to append to the file. Each element takes user input without any issues. but when they go to write a second Horse tot he file is wipes out the old one and make a whole new file.
Any suggestions on how to append would be great
void WriteThisHorseToFile(char* horseName, char* horseMother, char* horseFather, char* horseHeight,
char* horseOwner, char* horseAge, char* horseWins, char* horseMarkings, char* horseNotes)
{
TiXmlDocument doc;
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
doc.LinkEndChild( decl );
TiXmlElement * root = new TiXmlElement( "Horses" );
doc.LinkEndChild( root );
TiXmlElement * element2 = new TiXmlElement( "Name" );
root->LinkEndChild( element2 );
TiXmlText * text2 = new TiXmlText(horseName);
element2->LinkEndChild( text2 );
TiXmlElement * element3 = new TiXmlElement( "Mother" );
element2->LinkEndChild( element3 );
TiXmlText * text3 = new TiXmlText(horseMother);
element2->LinkEndChild( text3 );
TiXmlElement * element4 = new TiXmlElement( "Father" );
element2->LinkEndChild( element4 );
TiXmlText * text4 = new TiXmlText(horseFather);
element2->LinkEndChild( text4 );
TiXmlElement * element5 = new TiXmlElement( "Height" );
element2->LinkEndChild( element5 );
TiXmlText * text5 = new TiXmlText(horseHeight);
element2->LinkEndChild( text5 );
TiXmlElement * element6 = new TiXmlElement( "Owner" );
element2->LinkEndChild( element6 );
TiXmlText * text6 = new TiXmlText(horseOwner);
element2->LinkEndChild( text6 );
TiXmlElement * element7 = new TiXmlElement( "Age" );
element2->LinkEndChild( element7 );
TiXmlText * text7 = new TiXmlText(horseAge);
element2->LinkEndChild( text7 );
TiXmlElement * element8 = new TiXmlElement( "Wins" );
element2->LinkEndChild( element8 );
TiXmlText * text8 = new TiXmlText(horseWins);
element2->LinkEndChild( text8 );
TiXmlElement * element9 = new TiXmlElement( "Markings" );
element2->LinkEndChild( element9 );
TiXmlText * text9 = new TiXmlText(horseMarkings);
element2->LinkEndChild( text9 );
TiXmlElement * element10 = new TiXmlElement( "Notes" );
element2->LinkEndChild( element10 );
TiXmlText * text10 = new TiXmlText(horseNotes);
element2->LinkEndChild( text10 );
dump_to_stdout( &doc );
doc.SaveFile("demo2.xml");
PressEnter();
}
Sorry first time posting and just getting used to layout of site.
How i solved the appending issue for the xml file.
turns out it was quite simple. I will make use the example above.
it is not the cleanest of code but the example still applies.
Now that it is working i can tidy up the code a bit.
I just hope this helps other see how it can be done.
void WriteThisHorseToFile(char* horseName, char* horseMother, char* horseFather, char* horseHeight,
char* horseOwner, char* horseAge, char* horseWins, char* horseMarkings, char* horseNotes)
TiXmlDocument doc;
doc.LoadFile ("horses.xml");
TiXmlElement* root = doc.FirstChildElement( "Horses" );
if ( root )
{
TiXmlElement * element2 = new TiXmlElement( "Name" );
root->LinkEndChild( element2 );
TiXmlText * text2 = new TiXmlText(horseName);
element2->LinkEndChild( text2 );
//add as many child links as you wish :D
}
else
{
TiXmlDocument doc;
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
doc.LinkEndChild( decl );
TiXmlElement * root = new TiXmlElement( "Horses" );
doc.LinkEndChild( root );
TiXmlElement * element2 = new TiXmlElement( "Name" );
root->LinkEndChild( element2 );
TiXmlText * text2 = new TiXmlText(horseName);
element2->LinkEndChild( text2 );
//add as many child links as you wish :D
}
Related
I am using three.js to create a simple 3d Object ( CylinderGeometry) in the Matterport.
So i want to make a colision detection with a wall using SDK for the 3d Obj
So there is the code for the cylinder implementation
const THREE = this.context.three;
const textureLoader = new THREE.TextureLoader();
const geometry = new THREE.CylinderGeometry( 0.09, 0.09, 5, 5 );
geometry.rotateZ(-Math.PI * 0.5);
const material = new THREE.MeshBasicMaterial( {color: this.finalColor } );
const cylinder = new THREE.Mesh( geometry, material );
cylinder.name = "poiCylinder";
if (!this.inputs.sprite) {
return;
}
if (!this.inputs.sprite.startsWith('/assets/')) {
textureLoader.crossOrigin = 'Anonymous';
}
let map;
if (this.inputs.sprite.indexOf('.gif') !== -1) {
map = new GifLoader().load(this.inputs.sprite);
} else {
map = textureLoader.load(this.inputs.sprite);
}
map.minFilter = THREE.LinearFilter;
map.wrapS = map.wrapT = THREE.ClampToEdgeWrapping;
this.material = new THREE.SpriteMaterial( { map, color: this.inputs.color, fog: false }
);
this.material.alphaTest = 0.5;
this.material.map.encoding = THREE.sRGBEncoding;
this.sprite = new THREE.Sprite( this.material );
this.sprite.add(cylinder);
this.onObjectReady(this.sprite, true);
I am trying to work out if there is benefit to using Redis to cache data. But MongoDb seems to write data faster. This is with a single Mongo db without replication.
I compare Redis pipe and batch saves, saving 100k rows, to saving to MongoDb, 1 or 100 rows at a time. I also compare flattening 100 rows into a single document or Redis value for faster saving.
Results:
Mongo: Saved 100000 rows, 100 rows at a time, 1564 elapsed milliseconds: 0.01564 ms per row. Num rows inserted: 100000
Redis list pipe Saved 100000 rows to, 100 row at a time, 2030 elapsed milliseconds: 0.0203 ms per row. new listLength: 100000
Redis list batch Saved 100000 rows, 100 row at a time, 2101 elapsed milliseconds: 0.02101 ms per row. new listLength: 100000
Redis list pipe complex Saved 100000 rows to, 10000 rows at a time, total elapsedMilliseconds: 187; 0.00187 ms per row. new listLength: 1000
Mongo: complex Saved 100000 rows, 10000 rows at a time, total 135 elapsed milliseconds: 0.00135 ms per row. Num rows inserted: 1000
To run the below C# code, use MSVS 2019 and use Nuget to add StackExchange.Redis, MongoDB.Driver and Newtonsoft.Json.
Conclusion: MongoDb saves faster. Can anyone say why this test is unfair? I need to know if I'm wrong before we go down the MongoDb path and ignore a caching layer.
using System;
using System.Collections.Generic;
using MongoDB.Driver;
using StackExchange.Redis;
using Newtonsoft.Json;
using System.Threading.Tasks;
namespace MongoAndRedisPerformanceTests
{
public class MGpsDatumJsonComplex
{
public MGpsDatumJsonComplex( string pJsonComplex )
{
jsonComplex = pJsonComplex;
}
public string jsonComplex { get; set; }
}
public class MGpsDatum
{
public MGpsDatum( int pUnitID, float pX, float pY, DateTime pTimeStamp, byte pSpeedKmph, float? pDistanceKM, DateTime? pTimeInsertedToProviderDb, int pOptionTemplateID )
{
ID = -1;
UnitID = pUnitID;
X = pX;
Y = pY;
TimeStamp = pTimeStamp;
SpeedKmph = pSpeedKmph;
DistanceKM = pDistanceKM;
TimeInsertedToProviderDb = pTimeInsertedToProviderDb;
OptionTemplateID = pOptionTemplateID;
extRef = "1000000000";
}
public string extRef { get; set; }
public int ID { get; set; }
public int UnitID { get; set; }
public float X { get; set; }
public float Y { get; set; }
public DateTime TimeStamp { get; set; }
public float? DistanceKM { get; set; }
public byte SpeedKmph { get; set; }
public int? OptionTemplateID { get; set; }
public DateTime? TimeInsertedToProviderDb { get; set; }
public float? OdoKm { get; set; }
public float? AuxFloat1 { get; set; }
public bool HasStoppedOrAtStopStatus { get; set; }
public DateTime TimeSavedToOSGPSdb { get; set; }
}
class Program
{
static void MongoDataSaveSpeedTest()
{
MongoClientSettings mongo_settings = new MongoClientSettings();
mongo_settings.Server = new MongoServerAddress( "127.0.0.1" );
MongoDB.Driver.MongoClient client = new MongoClient( mongo_settings );
IMongoDatabase db = client.GetDatabase( "OpsiService" );
IMongoCollection<MGpsDatum> posCollection = db.GetCollection<MGpsDatum>( "GpsDataSpeedTest" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
DateTime start = DateTime.Now;
int numRows = 10000;
for (int i = 0; i < numRows; i++)
{
posCollection.InsertOne( gpsDatum );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
Console.WriteLine( "Saved " + numRows + " rows to Mongo collection, 1 row at a time, " + elapsedMilliseconds + " elapsed milliseconds: " + ((float) ((float) elapsedMilliseconds)/ ((float) numRows ) ) + " ms per row." );
int br = 0;
}
static void MongoDataSaveSpeedTest_MultiInsert( int numRows, int batchSize )
{
MongoClientSettings mongo_settings = new MongoClientSettings();
mongo_settings.Server = new MongoServerAddress( "127.0.0.1" );
MongoDB.Driver.MongoClient client = new MongoClient( mongo_settings );
IMongoDatabase db = client.GetDatabase( "OpsiService" );
db.DropCollection( "GpsDataSpeedTest" );
IMongoCollection<MGpsDatum> posCollection = db.GetCollection<MGpsDatum>( "GpsDataSpeedTest" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
List<MGpsDatum> listGpsDatum = new List<MGpsDatum>( batchSize );
for (int i=0; i< batchSize; i++)
{
listGpsDatum.Add( gpsDatum );
}
DateTime start = DateTime.Now;
for (int i = 0; i < numRows/batchSize; i++)
{
posCollection.InsertMany( listGpsDatum );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long numRowsAfterInsert = posCollection.CountDocuments( FilterDefinition<MGpsDatum>.Empty );
Console.WriteLine( "Mongo: Saved " + numRows + " rows, " + batchSize + " rows at a time, " + elapsedMilliseconds + " elapsed milliseconds: " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. Num rows inserted: " + numRowsAfterInsert );
}
static void MongoDataSaveSpeedTest_MultiInsert_complex( int numRows, int batchSize, int numRowsInRecord )
{
MongoClientSettings mongo_settings = new MongoClientSettings();
mongo_settings.Server = new MongoServerAddress( "127.0.0.1" );
MongoDB.Driver.MongoClient client = new MongoClient( mongo_settings );
IMongoDatabase db = client.GetDatabase( "OpsiService" );
db.DropCollection( "GpsDataSpeedTestComplex" );
IMongoCollection<MGpsDatumJsonComplex> posCollection = db.GetCollection<MGpsDatumJsonComplex>( "GpsDataSpeedTestComplex" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
List<MGpsDatum> complexGpsDatum = new List<MGpsDatum>( numRowsInRecord );
for (int i=0; i<numRowsInRecord; i++)
{
complexGpsDatum.Add( gpsDatum );
}
List<MGpsDatumJsonComplex> listComplexGpsDatum = new List<MGpsDatumJsonComplex>( batchSize );
string complextGpsDatumStr = JsonConvert.SerializeObject( complexGpsDatum );
MGpsDatumJsonComplex complexJson = new MGpsDatumJsonComplex( complextGpsDatumStr );
for (int i = 0; i < batchSize; i++)
{
listComplexGpsDatum.Add( complexJson );
}
DateTime start = DateTime.Now;
for (int i = 0; i < numRows / (batchSize*numRowsInRecord ) ; i++)
{
posCollection.InsertMany( listComplexGpsDatum );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long numRowsAfterInsert = posCollection.CountDocuments( FilterDefinition<MGpsDatumJsonComplex>.Empty );
Console.WriteLine( "Mongo: complex Saved " + numRows + " rows, " + batchSize*numRowsInRecord + " rows at a time, total " + elapsedMilliseconds + " elapsed milliseconds: " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. Num rows inserted: " + numRowsAfterInsert );
}
// https://stackoverflow.com/questions/27796054/pipelining-vs-batching-in-stackexchange-redis
static void RedisSaveSpeedTest_Pipelining( int numRows, int batchSize )
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( "localhost:6379,connectTimeout=20000" );
IDatabase db = redis.GetDatabase( 1 );
db.KeyDelete( "GpsTestQueue" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
string gpsDatumJson = JsonConvert.SerializeObject( gpsDatum );
DateTime start = DateTime.Now;
for (int b = 0; b < numRows / batchSize; b++)
{
List<Task> addTasks = new List<Task>();
for (int i = 0; i < batchSize; i++)
{
Task<long> addAsync = db.ListLeftPushAsync( "GpsTestQueue", gpsDatumJson );
addTasks.Add( addAsync );
}
Task[] tasks = addTasks.ToArray();
Task.WaitAll( tasks );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long listLength = db.ListLength( "GpsTestQueue" );
Console.WriteLine( "Redis list pipe Saved " + numRows + " rows to, " + batchSize + " row at a time, " + elapsedMilliseconds + " elapsed milliseconds: " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. new listLength: " + listLength );
}
// https://stackoverflow.com/questions/27796054/pipelining-vs-batching-in-stackexchange-redis
static void RedisSaveSpeedTest_Batching( int numRows, int batchSize )
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( "localhost:6379,connectTimeout=20000" );
IDatabase db = redis.GetDatabase( 1 );
db.KeyDelete( "GpsTestQueue" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
string gpsDatumJson = JsonConvert.SerializeObject( gpsDatum );
DateTime start = DateTime.Now;
for (int b = 0; b < numRows / batchSize; b++)
{
List<Task> addTasks = new List<Task>();
IBatch batch = db.CreateBatch();
for (int i = 0; i < batchSize; i++)
{
Task<long> addAsync = db.ListLeftPushAsync( "GpsTestQueue", gpsDatumJson );
addTasks.Add( addAsync );
}
batch.Execute();
Task[] tasks = addTasks.ToArray();
Task.WaitAll( tasks );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long listLength = db.ListLength( "GpsTestQueue" );
Console.WriteLine( "Redis list batch Saved " + numRows + " rows, " + batchSize + " row at a time, " + elapsedMilliseconds + " elapsed milliseconds: " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. new listLength: " + listLength );
}
static void RedisSaveSpeedTest_Pipelining_complex( int numRows, int batchSize, int numRowsInRecord )
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( "localhost:6379,connectTimeout=20000" );
IDatabase db = redis.GetDatabase( 1 );
db.KeyDelete( "GpsTestQueue" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
string gpsDatumJson = JsonConvert.SerializeObject( gpsDatum );
string gpsDatumJsonComplex = "";
for (int i=0; i < numRowsInRecord; i++)
{
gpsDatumJsonComplex += gpsDatumJson;
}
DateTime start = DateTime.Now;
int numBatchSaves = numRows / (numRowsInRecord * batchSize);
for (int b = 0; b < numBatchSaves; b++)
{
List<Task> addTasks = new List<Task>();
for (int i = 0; i < batchSize; i++)
{
Task<long> addAsync = db.ListLeftPushAsync( "GpsTestQueue", gpsDatumJsonComplex );
addTasks.Add( addAsync );
}
Task[] tasks = addTasks.ToArray();
Task.WaitAll( tasks );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long listLength = db.ListLength( "GpsTestQueue" );
Console.WriteLine( "Redis list pipe complex Saved " + numRows + " rows to, " + batchSize* numRowsInRecord + " rows at a time, total elapsedMilliseconds: " + elapsedMilliseconds + "; " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. new listLength: " + listLength );
}
static void RedisSaveSpeedTest()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect( "localhost:6379,connectTimeout=20000" );
IDatabase db = redis.GetDatabase( 1 );
db.KeyDelete( "GpsTestQueue" );
MGpsDatum gpsDatum = new MGpsDatum( 1, 1, 1, DateTime.Now, 0, null, DateTime.Now, 1 );
string gpsDatumJson = JsonConvert.SerializeObject( gpsDatum );
DateTime start = DateTime.Now;
int numRows = 10000;
for (int i = 0; i < numRows; i++)
{
db.ListLeftPush( "GpsTestQueue", gpsDatumJson );
}
int elapsedMilliseconds = (int)(DateTime.Now - start).TotalMilliseconds;
long listLength = db.ListLength( "GpsTestQueue" );
Console.WriteLine( "batch Saved " + numRows + " rows to Redis collection, 1 row at a time, " + elapsedMilliseconds + " elapsed milliseconds. " + ((float)((float)elapsedMilliseconds) / ((float)numRows)) + " ms per row. new listLength: " + listLength );
int br = 0;
}
static void Main( string[] args )
{
//MongoDataSaveSpeedTest();
//RedisSaveSpeedTest();
int batchSize = 100;
int numRows = 100000;
int numRowsInRecord = 100;
MongoDataSaveSpeedTest_MultiInsert( numRows, batchSize );
RedisSaveSpeedTest_Pipelining( numRows, batchSize );
RedisSaveSpeedTest_Batching( numRows, batchSize );
RedisSaveSpeedTest_Pipelining_complex( numRows, batchSize, numRowsInRecord );
MongoDataSaveSpeedTest_MultiInsert_complex( numRows, batchSize, numRowsInRecord );
Console.ReadKey();
}
}
}
i’m new to three.js and i was creating a custom shape using multiple objects. But the problem i’m facing is that when i add all the objects to the scene its working fine.
but whenever i merged all the object in a single geometry and then add to a scene, it becomes like this. see the image
don't know why it is getting darker but the bottom and back part seems to be fine.
The code i’ve used is shown below
var loader = new THREE.TextureLoader();
if(globalTextureImage != null)
{
var texture = loader.load( globalTextureImage );
}
else
{
var texture = loader.load( 'my_texture/1.jpg' );
}
var topGeometry = new THREE.CubeGeometry( 175, 0, 40, 0, 0, 0 );
var top = new THREE.Mesh( topGeometry, new THREE.MeshBasicMaterial({map:texture}) );
top.position.x = -0.01;
top.position.y = 0.99;
top.position.z = -0.003;
top.scale.x = 0.0198;
top.scale.y = -0.008;
top.scale.z = 0.0355;
top.updateMatrix();
var bottomGeometry = new THREE.CubeGeometry( 175, 0, 40, 1, 1, 1);
var bottom = new THREE.Mesh( bottomGeometry, new THREE.MeshBasicMaterial({map:texture}) );
bottom.position.x = -0.01;
bottom.position.y = -0.01;
bottom.position.z = -0.003;
bottom.scale.x = 0.0198;
bottom.scale.y = -0.008;
bottom.scale.z = 0.0355;
bottom.updateMatrix();
var leftGeometry = new THREE.CubeGeometry( 1, 100, 40, 1, 1, 1 );
var left = new THREE.Mesh( leftGeometry, new THREE.MeshBasicMaterial({map:texture}) );
left.position.x = -1.74;
left.position.y = 0.49;
left.position.z = -0.003;
left.scale.x = 0.01;
left.scale.y = -0.01;
left.scale.z = 0.035;
left.updateMatrix();
var rightGeometry = new THREE.CubeGeometry( 0, 100, 40, 1, 1, 1 );
var right = new THREE.Mesh( rightGeometry, new THREE.MeshBasicMaterial({map:texture}) );
right.position.x = 1.719;
right.position.y = 0.49;
right.position.z = -0.003;
right.scale.x = 0.01;
right.scale.y = -0.01;
right.scale.z = 0.035;
right.updateMatrix();
var middleGeometry = new THREE.CubeGeometry( 346, 100, 0, 1, 1, 1 );
var middle = new THREE.Mesh( middleGeometry, new THREE.MeshBasicMaterial({map:texture}) );
middle.position.x = -0.01;
middle.position.y = 0.49;
middle.position.z = 0.69;
middle.scale.x = 0.01;
middle.scale.y = -0.01;
middle.scale.z = 0.035;
middle.updateMatrix();
var backGeometry = new THREE.CubeGeometry( 345, 100, 0, 1, 1, 1 );
var back = new THREE.Mesh( backGeometry, new THREE.MeshBasicMaterial({map:texture}) );
back.position.x = -0.02;
back.position.y = 0.49;
back.position.z = -0.69;
back.scale.x = 0.01;
back.scale.y = -0.01;
back.scale.z = 0.035;
back.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 20, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinder = new THREE.Mesh( geometry, material );
cylinder.scale.set(0.02,0.02, 0.02);
cylinder.position.x = -0;
cylinder.position.y = 0.45;
cylinder.position.z = 0.82;
cylinder.rotation.x = 1.86;
cylinder.rotation.y = 3.14;
cylinder.rotation.z = 1.56;
cylinder.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 8, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinderleft = new THREE.Mesh( geometry, material );
cylinderleft.scale.set(0.02,0.02, 0.02);
cylinderleft.position.x = -0.18;
cylinderleft.position.y = 0.45;
cylinderleft.position.z = 0.74;
cylinderleft.rotation.x = 1.6;
cylinderleft.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 8, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinderRight = new THREE.Mesh( geometry, material );
cylinderRight.scale.set(0.02,0.02, 0.02);
cylinderRight.position.x = 0.18;
cylinderRight.position.y = 0.45;
cylinderRight.position.z = 0.74;
cylinderRight.rotation.x = 1.6;
cylinderRight.updateMatrix();
// scene.add( cylinder );
// scene.add( cylinderleft );
// scene.add( cylinderRight );
// scene.add(top);
// scene.add(bottom);
// scene.add(left);
// scene.add(right);
// scene.add(middle);
// scene.add(back);
var singleGeometry = new THREE.Geometry();
singleGeometry.merge(top.geometry, top.matrix);
singleGeometry.merge(bottom.geometry, bottom.matrix);
singleGeometry.merge(left.geometry, left.matrix);
singleGeometry.merge(right.geometry, right.matrix);
singleGeometry.merge(middle.geometry, middle.matrix);
singleGeometry.merge(back.geometry, back.matrix);
singleGeometry.merge(cylinder.geometry, cylinder.matrix);
singleGeometry.merge(cylinderleft.geometry, cylinderleft.matrix);
singleGeometry.merge(cylinderRight.geometry, cylinderRight.matrix);
var material = new THREE.MeshLambertMaterial({map:texture});
var mesh = new THREE.Mesh(singleGeometry, material);
mesh.scale.set(0.5,0.5,0.5);
objects.push(mesh);
scene.add(mesh);
Any help would be really appreciated
When you draw the object separately, the you create a THREE.Mesh for each object, each with a THREE.MeshBasicMaterial. The behaviour of a THREE.MeshBasicMaterial that the object appears with the brightness on each side, independent on the light of the scene.
But when you merge the object the you use a THREE.MeshLambertMaterial for the THREE.Geometry. This causes that the brightness of the object depends on the light of the scene. The parts of the object which face the light appear bright. Areas away from the light are dark.
If you would use THREE.MeshBasicMaterial for the merged geometry too, then the appearance would be the same as when you draw all the objects separately.
Can we display data in pie chart slice and also tolltip like the above image using chart.js?
Updated:
Here is my code in php page.
printf( '<table>' );
echo '<tr><td style="text-align: right;"><canvas id="pie-canvas-'
. $canvasId
. '" width=256px height=257px ></canvas></td><td style="text-align: left;width:360px;" id="legend" class="chart-legend"></td></tr>';
echo '<script type="text/javascript">drawPie('
. $canvasId
. ', '
. $data
.', '
. $legend
. ');</script>';
printf( '</table>' );
printf( '<script type="text/javascript" src="extlib/Chart.min.js"></script>' );
printf( '<script type="text/javascript" src="extlib/jquery-min.js"></script>' );
printf( '<script type="text/javascript">' );
?>
function drawPie( canvasId, data, legend )
{
//pie chart for machine status
var canvas = document.getElementById( "pie-canvas-" + canvasId );
var ctx = canvas.getContext( "2d" );
var midX = canvas.width/2;
var midY = canvas.height/2;
var piedata = [];
$.each(data,function(i,val){
piedata.push({value:val.hostStatusCount,color:val.color,label:val.status});
});
Chart.types.Pie.extend({
name: "PieAlt",
draw: function(){
Chart.types.Pie.prototype.draw.apply(this, arguments);
drawSegmentValues(this)
}
});
var myPieChart = new Chart(ctx).PieAlt(piedata, {
showTooltips: true,
tooltipTemplate: "<%= Math.round(circumference / 6.283 * 100) %>%"
});
var radius = myPieChart.outerRadius;
function drawSegmentValues(myPieChart)
{
//displays segements(number of machines) for each slice of pie in percentage
var length = myPieChart.segments.length;
var totalValue = 0;
for ( var i=0; i < length; i++ )
{
totalValue +=myPieChart.segments[i].value;
}
for( var i=0; i < length; i++ )
{
ctx.fillStyle="black";
var textSize = canvas.width/15;
ctx.font= textSize+"px Verdana";
// Get needed variables
var value = Math.round( ( ( myPieChart.segments[i].value ) / totalValue ) * 100 );
var startAngle = myPieChart.segments[i].startAngle;
var endAngle = myPieChart.segments[i].endAngle;
var middleAngle = startAngle + ( ( endAngle - startAngle ) / 2 );
// Compute text location
var posX = ( radius /1.5 ) * Math.cos( middleAngle ) + midX;
var posY = ( radius/1.5 ) * Math.sin( middleAngle ) + midY;
// Text offside by middle
var w_offset = ctx.measureText( value ).width / 2;
var h_offset = textSize / 4;
ctx.fillText( value+"%", posX - w_offset, posY + h_offset );
}
}
//legend for status
if( legend )
document.getElementById("legend").innerHTML = myPieChart.generateLegend();
}
<?
When mouse over the data in pie slice moved from its position.
How to solve this?
Extend the chart and move your drawSegmentValues to inside the draw override, like so
Chart.types.Pie.extend({
name: "PieAlt",
draw: function(){
Chart.types.Pie.prototype.draw.apply(this, arguments);
drawSegmentValues(this)
}
});
then use PieAlt
var myPieChart = new Chart(ctx).PieAlt(data, {
showTooltips: true,
tooltipTemplate: "<%= Math.round(circumference / 6.283 * 100) %>%"
});
and modify the drawSegmentValues function slightly
function drawSegmentValues(myPieChart)
{
var radius = myPieChart.outerRadius
...
Update
If you have a problem with the labels moving set the context textAlign and textBaseline properties, like so
...
ctx.font = textSize + "px Verdana";
ctx.textAlign = "start";
ctx.textBaseline = "bottom";
...
I need help with this code about Three.js. I do not know why it does not work, since everything is correct and copied from other codes that do work. The problem is that no Mouse Hovering effect works.
<html>
<head>
<title>NUEVO</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="js/libs/Tween.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.js"></script>
<script>
var scene,camera,rendered,projector;
var mouseX, mouseY, stats, container;
var objects=[];
var INTERSECTED;
var theta = 0;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 20000);
camera.position.set( 0, 150, 400 );
camera.lookAt(scene.position);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
projector = new THREE.Projector();
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
for (var i=0; i<3; i++)
{
var geometry = new THREE.CubeGeometry(40,40,40);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
cube.position.x = (i*200) -200
objects.push(cube);
scene.add(cube);
}
window.addEventListener( 'resize', onWindowResize, false );
}
function onDocumentMouseDown( event )
{
event.preventDefault();
mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseY = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame(animate);
render();
update();
}
function update()
{
var vector = new THREE.Vector3( mouseX, mouseY, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( intersects[ 0 ].object != INTERSECTED )
{
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex( 0xffff00 );
} else {// there are no intersections
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
/* for(var i=0; i<3; i++)
{
objects[i].rotation.y += 0.05;
}*/
}
}
function render()
{
//theta += 0.4;
camera.position.x = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.y = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.z = 300 * Math.cos( theta * Math.PI / 360 );
camera.lookAt( scene.position );
renderer.render(scene, camera);
}
</script>
</body>
</html>
This is what You want:
http://jsfiddle.net/Lx6nE/4/
What was wrong:
The link to Three.js should be towards the minified source.
The braces should be indented right becuase of flickering
The mousedown event should be captured.
The code:
var scene,camera,rendered,projector;
var mouseX, mouseY, stats, container;
var objects=[];
var INTERSECTED;
var theta = 0;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 20000);
camera.position.set( 0, 150, 400 );
camera.lookAt(scene.position);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
projector = new THREE.Projector();
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
for (var i=0; i<3; i++)
{
var geometry = new THREE.CubeGeometry(40,40,40);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
cube.position.x = (i*50) -60
objects.push(cube);
scene.add(cube);
}
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
event.preventDefault();
mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseY = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame(animate);
render();
update();
}
function update()
{
var vector = new THREE.Vector3( mouseX, mouseY, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( intersects[ 0 ].object != INTERSECTED )
{
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex( 0xffff00 );
}
} else {// there are no intersections
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
/* for(var i=0; i<3; i++)
{
objects[i].rotation.y += 0.05;
}*/
}
}
function render()
{
//theta += 0.4;
camera.position.x = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.y = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.z = 300 * Math.cos( theta * Math.PI / 360 );
camera.lookAt( scene.position );
renderer.render(scene, camera);
}