three.js Cannot read property 'center' of undefined - javascript
I'm trying to load a 3D model of a cube onto a 3D Force Directed Graph using GLTFLoader in three.js. The project is built using Angular.
The model is loaded, showing GLTFLoader: 23.507080078125ms but the object is not displayed. It further gives an error showing,
ERROR TypeError: Cannot read property 'center' of undefined
at Sphere.copy (three.module.js:5347)
at Mesh.raycast (three.module.js:14240)
at intersectObject (three.js:42091)
at Raycaster.intersectObjects (three.js:42164)
at animate (3d-force-graph.module.js:386)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:398)
at Object.onInvokeTask (core.es5.js:4136)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:397)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask (zone.js:165)
at ZoneTask.invoke (zone.js:460)
at timer (zone.js:1732)
The code to load the model is as below:
var manager = new THREE.LoadingManager();
var loader = new GLTFLoader(manager);
loader.load(
// resource URL
'assets/model/cube.gltf',
// called when the resource is loaded
function ( gltf ) {
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.material = gltf.materials;
}
} );
var cube = gltf.scene; // Object
self.showGraph(gData,cube,themeNum);
console.log("graph drawn");
},
// called when loading is in progresses
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened -- ' + error );
}
);
// function to draw the graph -- to be executed on 3D model load
showGraph(gData:any, cube:any, themeNum: any){
const Graph = ForceGraph3D()
(document.getElementById('3d-graph'))
.nodeThreeObject(({ group }) => new THREE.Mesh(
[
new THREE.BoxGeometry(Math.random() * 20, Math.random() * 20, Math.random() * 20),
cube,
new THREE.CylinderGeometry(Math.random() * 10, Math.random() * 10, Math.random() * 20),
new THREE.DodecahedronGeometry(Math.random() * 10),
new THREE.SphereGeometry(Math.random() * 10),
new THREE.TorusGeometry(Math.random() * 10, Math.random() * 2),
new THREE.TorusKnotGeometry(Math.random() * 10, Math.random() * 2)
][group],
new THREE.MeshLambertMaterial({
color: this.themes[themeNum][group],
transparent: true,
opacity: 0.75
})
))
.nodeAutoColorBy('group')
.onNodeClick(node => {
this.attach3DNodeClickEvent(node);
})
.graphData(gData);
}
The cube.gltf file exported from Blender is as below:
{
"accessors" : [{
"bufferView" : 0,
"componentType" : 5121,
"count" : 36,
"max" : [23],
"min" : [0],
"type" : "SCALAR"
}, {
"bufferView" : 1,
"componentType" : 5126,
"count" : 24,
"max" : [1, 1, 1],
"min" : [-1, -1, -1],
"type" : "VEC3"
}, {
"bufferView" : 2,
"componentType" : 5126,
"count" : 24,
"max" : [1, 1, 1],
"min" : [-1, -1, -1],
"type" : "VEC3"
}],
"asset" : {
"generator" : "Khronos Blender glTF 2.0 exporter",
"version" : "2.0"
},
"bufferViews" : [{
"buffer" : 0,
"byteLength" : 36,
"byteOffset" : 0,
"target" : 34963
}, {
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 36,
"target" : 34962
}, {
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 324,
"target" : 34962
}],
"buffers" : [{
"byteLength" : 612,
"uri" : "cube.bin"
}],
"materials" : [{
"name" : "Material",
"pbrMetallicRoughness" : {
"baseColorFactor" : [0.114473, 0.362915, 0.64, 1],
"metallicFactor" : 0
}
}],
"meshes" : [{
"name" : "Cube",
"primitives" : [{
"attributes" : {
"NORMAL" : 2,
"POSITION" : 1
},
"indices" : 0,
"material" : 0
}]
}],
"nodes" : [{
"name" : "Camera",
"rotation" : [0.483536, 0.336872, -0.208704, 0.780483],
"translation" : [7.48113, 5.34367, 6.50764]
}, {
"mesh" : 0,
"name" : "Cube"
}, {
"name" : "Lamp",
"rotation" : [0.169076, 0.75588, -0.272171, 0.570948],
"scale" : [1, 1, 1],
"translation" : [4.07625, 5.90386, -1.00545]
}],
"scene" : 0,
"scenes" : [{
"name" : "Scene",
"nodes" : [1, 2, 0]
}]
}
What am I doing wrong here? The examples on three.js docs seem to be the same.
Any help is much appreciated.
According to the error, you're performing a raycast in your animate function, which is where the error is occurring. Specifically, the error is happening when the raycast process is trying to copy an object's bounding sphere.
// three.js r91, Mesh.js, line 237
sphere.copy( geometry.boundingSphere );
It's saying it can't find property center on geometry.boundingSphere, because geometry.boundingSphere is undefined.
Unless GLTFLoader automatically computes bounding spheres, this information isn't automatically populated. You'll need to call geometry.computeBoundingSphere() before calling raycast on an object. If GLTFLoader isn't doing this job, then you'll likely need to do it for the whole scene.
Running this code after the data is loaded (and before starting animate) will populate all of the objects' bounding spheres:
scene.traverse(function(node){
if(node.geometry){
node.geometry.computeBoundingSphere();
}
});
Related
TopoJSON in Leaflet, via Omnivore: reading properties
While following along a tutorial on choropleth maps in Leaflet I realized that a Shapefile > GeoJSON conversion generated a very large file. TopoJSON proved a better alternative, except for being unable to access the properties for each geometry. I merged data from https://github.com/centraldedados/violencia-domestica into a TopoJSON file converted from a Shapefile, structured like so: { "transform": { "scale": [ 0.0025081552497290688, 0.0012125352320998587 ], "translate": [ -31.26818656921381, 30.03017616271984 ] }, "objects": {"PRT_adm1": { "geometries": [ { "type": "Polygon", "arcs": [[ 0, 1, 2, 3, 4 ]], "properties": { "ENGTYPE_1": "District", "ISO": "PRT", "NL_NAME_1": null, "HASC_1": "PT.EV", "ID_0": 182, "NAME_0": "Portugal", "TYPE_1": "Distrito", "ID_1": 1, "NAME_1": "Évora", "CCN_1": 0, "CCA_1": null, "dgai_violencia_domestica_2008_2014": { "Valores": [ { "Ano": "2009", "Entidade": [ {"GNR": "216"}, {"PSP": "171"} ] }, { "Ano": "2010", "Entidade": [ {"GNR": "247"}, {"PSP": "162"} ] }, { "Ano": "2011", "Entidade": [ {"GNR": "248"}, {"PSP": "181"} ] }, { "Ano": "2012", "Entidade": [ {"GNR": "277"}, {"PSP": "150"} ] }, { "Ano": "2013", "Entidade": [ {"GNR": "207"}, {"PSP": "169"} ] }, { "Ano": "2014", "Entidade": [ {"GNR": "226"}, {"PSP": "137"} ] } ], "Distrito": "Évora", "Factor_amostra": 0.020521270111203194, "Somatorio_amostra": 2391 }, "VARNAME_1": null } }, ... and would like to access the "dgai_violencia_domestica_2008_2014.Factor_amostra" property of each object, so as to encode a color value. Is this possible with Leaflet+Omnivore, or would d3 or another library be needed? A current, broken version of the map lives here, with the relevant code being: L.mapbox.accessToken = '...'; var map = L.mapbox.map('map', 'mapbox.streets').setView([39.5, -8.60], 7); // Omnivore will AJAX-request this file behind the scenes and parse it: // note that there are considerations: // - The file must either be on the same domain as the page that requests it, // or both the server it is requested from and the user's browser must // support CORS. // Internally this function uses the TopoJSON library to decode the given file // into GeoJSON. function getColor(d) { return d > 0.75 ? '#800026' : d > 0.50 ? '#FC4E2A' : d > 0.25 ? '#FD8D3C' : '#FFEDA0'; } var pt = omnivore.topojson('dgai_violencia_domestica_2008_2014.topo.json'); function style(geometry) { return { fillColor: getColor(geometry.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra), weight: 1, opacity: 1, color: 'white', dashArray: '3', fillOpacity: 1 }; } pt.setStyle(style); pt.addTo(map); A nudge in the right direction, anyone? Thanks in advance.
Did some testing and as it turns out, the setStyle function won't execute: pt.setStyle(function (feature) { console.log('Yay, i am executed!'); return { 'color': 'red' } }); Using that Yay, i am executed! never gets logged to the console. Which made me suspect that there's something wrong with the setStyle method of Omnivore. So i tried it with a custom layer: var geojson = new L.GeoJSON(null); var pt = omnivore.topojson(url, null, geojson).addTo(map); geojson.setStyle(function (feature) { console.log('Yay, i am executed!'); return { 'color': 'red' }; }); Same thing, Yay, i am executed! never get logged to the console. One thing left to try was the style option of L.GeoJSON: var geojson = new L.GeoJSON(null, { 'style': function (feature) { console.log('Yay, i am executed!'); return { 'color': 'red' }; } }); var pt = omnivore.topojson(url, null, geojson).addTo(map); And lo and behold, that does what it's supposed to do. So i tried it with your style and color function and dataset: function getColor(d) { return d > 0.75 ? '#800026' : d > 0.50 ? '#FC4E2A' : d > 0.25 ? '#FD8D3C' : '#FFEDA0'; } function getStyle (feature) { return { fillColor: getColor(feature.properties.dgai_violencia_domestica_2008_2014.Peso_na_duracao_da_amostra), weight: 1, opacity: 1, color: 'white', dashArray: '3', fillOpacity: 1 }; } var geojson = new L.GeoJSON(null, { 'style': getStyle }); var pt = omnivore.topojson(url, null, geojson).addTo(map); This gives me the following error: Uncaught TypeError: Cannot read property 'Peso_na_duracao_da_amostra' of undefined That's because on the third feature, that property is missing. So your dataset is corrupt or incomplete. Hopefully this will help you along, good luck, here's a Plunker of my experiment which works (so far): http://plnkr.co/edit/P6t96hTaOgSxTc4TPUuV?p=preview
Three.js - include mesh data in code
I have this Three.js code with JSON loader loading mesh from file /models/mountain.json: var Three = new function () { this.scene = new THREE.Scene() this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000) this.camera.position.set(20, 52, 20); this.camera.rotation.order = 'YXZ'; this.camera.rotation.y = -Math.PI / 4; this.camera.rotation.x = Math.atan(-1 / Math.sqrt(2)); this.camera.scale.addScalar(1); this.renderer = new THREE.WebGLRenderer() this.renderer.setSize(window.innerWidth, window.innerHeight); var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry(436, 624), new THREE.MeshLambertMaterial({color: '#808080'})); ground.rotation.x = -Math.PI / 2; //-90 degrees around the x axis this.scene.add(ground); var light = new THREE.PointLight(0xFFFFDD); light.position.set(-1000, 1000, 1000); this.scene.add(light); var loader = new THREE.JSONLoader(); this.loadMountain = function (x, y) { loader.load('/models/mountain.json', Three.getGeomHandler('#808080', x, y, 1)) } this.loadFields = function () { for (var i=0;i<4000;i++) { Three.loadMountain(x, y) } } this.getGeomHandler = function (color, x, y, scale) { return function (geometry) { var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color: color})); mesh.scale.set(scale, scale, scale); mesh.position.set(x, 0, y); Three.scene.add(mesh); }; } this.init = function () { $('body').append(Three.renderer.domElement); Three.loadFields() Three.render(); } this.render = function () { requestAnimationFrame(Three.render); Three.renderer.render(Three.scene, Three.camera); }; } $(document).ready(function () { Three.init(); }); and this is /models/mountain.json content: { "metadata": { "formatVersion" : 3.1, "generatedBy" : "Blender 2.7 Exporter", "vertices" : 39, "faces" : 62, "normals" : 36, "colors" : 0, "uvs" : [], "materials" : 1, "morphTargets" : 0, "bones" : 0 }, "scale" : 1.000000, "vertices" : [2.47941e-07,-1.13504e-07,-2.59668,-2.41031,-6.2081e-08,-1.42025,-2.2107,4.55942e-08,1.04307,2.16045,1.84802,0.183901,-0.427399,1.11956e-07,2.56126,1.23588,9.98242e-08,2.28371,2.50387,4.55942e-08,1.04307,2.58781,9.37308e-09,0.214431,2.17385,-0.0483214,-1.42025,1.40026,-0.0483214,-1.74566,1.50645e-07,2.13114,-1.9421,-0.6306,2.13114,-1.52968,-1.04238,2.48498,-1.06715,-1.23632,3,-0.856474,-1.5574,2.62306,-0.476759,-1.68478,2.74775,0.160378,-1.20001,3,0.780135,-1.14654,3,1.41015,-0.31966,3,1.91562,0.31966,2.48498,1.46763,0.92434,3,1.70803,0.754272,2.73835,0.751422,1.90443,2.61032,0.780134,1.52632,2.76301,0.160377,1.78144,2.69402,-0.47676,1.9564,3,-1.06223,0.807846,2.13114,-1.68984,1.32727,3.09213,-1.10549,1.13568,1.38919,-1.21096,1.98255,0.969716,-1.07503,0.529022,2.81989,0.43993,0.969891,3.32801,-1.43745,-0.39848,2.2361,-1.12285,-1.00579,1.31316,2.27174,-0.789081,1.31316,2.34614,0.888122,0.684588,2.17543,0.568656,2.07869,1.615,2.13863,1.49103,1.32889,2.52981,0.924307,0.978923], "faces" : [34,0,11,10,0,0,1,2,34,1,13,12,0,3,4,5,34,0,12,11,0,0,5,1,34,0,1,12,0,0,3,5,34,38,3,37,0,6,7,8,34,9,31,28,0,9,10,11,34,0,10,26,0,0,2,12,34,9,26,31,0,9,12,10,34,9,0,26,0,9,0,12,35,18,17,33,34,0,13,14,15,16,35,37,3,23,22,0,8,7,17,18,34,29,27,25,0,19,20,21,34,28,31,27,0,11,10,20,34,29,28,27,0,19,11,20,34,12,19,20,0,5,22,23,34,5,6,20,0,24,25,23,34,6,38,37,0,25,6,8,34,37,22,21,0,8,18,26,34,30,27,31,0,26,20,10,34,6,37,20,0,25,8,23,34,30,31,32,0,26,10,27,34,37,21,20,0,8,26,23,34,30,32,26,0,26,27,12,34,21,30,20,0,26,26,23,34,11,12,20,0,1,5,23,34,26,10,11,0,12,2,1,34,30,11,20,0,26,1,23,34,30,26,11,0,26,12,1,34,20,35,5,0,23,28,24,34,20,19,36,0,23,22,28,34,20,36,35,0,23,28,28,35,6,7,3,38,0,25,29,7,6,34,7,23,3,0,29,17,7,34,29,25,24,0,19,21,30,34,7,24,23,0,29,30,17,34,7,8,29,0,29,31,19,34,7,29,24,0,29,19,30,34,18,36,19,0,13,28,22,34,4,5,35,0,32,24,28,34,18,35,36,0,13,28,28,34,18,34,4,0,13,16,32,34,18,4,35,0,13,32,28,35,13,14,15,16,0,4,33,33,34,34,30,25,27,0,26,21,20,34,23,24,25,0,17,30,21,34,21,22,23,0,26,18,17,34,30,21,25,0,26,26,21,34,21,23,25,0,26,17,21,35,8,9,28,29,0,31,9,11,19,34,26,32,31,0,12,27,10,34,2,16,15,0,35,34,33,34,14,13,1,0,33,4,3,34,14,2,15,0,33,35,33,34,14,1,2,0,33,3,35,34,2,17,16,0,35,14,34,34,4,34,33,0,32,16,15,34,2,33,17,0,35,15,14,34,2,4,33,0,35,32,15,34,16,12,13,0,34,5,4,34,18,19,12,0,13,22,5,34,16,17,18,0,34,14,13,34,16,18,12,0,34,13,5], "uvs" : [], "normals" : [0.094028,0.298624,-0.949705,-0.162755,0.939238,-0.302133,0.228248,0.832942,-0.504044,-0.822016,0.351848,-0.447707,-0.253456,0.911466,-0.323923,-0.004059,0.913785,-0.40614,0.788598,0.576983,0.21247,0.952086,0.29432,-0.082797,0.625996,0.719138,0.301553,0.474441,0.29017,-0.83105,0.255501,0.796655,-0.547746,0.441328,0.166265,-0.881802,0.221656,0.483047,-0.847041,0.192999,0.761406,0.618824,-0.352977,0.778008,0.5197,-0.653584,0.252663,0.713401,-0.29136,0.293313,0.91052,0.688314,0.722556,0.063967,0.612629,0.761834,0.210364,0.718711,0.280313,-0.63625,0.370495,0.893033,-0.255287,0.629627,0.578692,-0.518326,0.229896,0.680258,0.695944,-0.064241,0.589251,0.805353,0.205145,0.606586,0.768059,0.734519,0.631458,0.24839,0.211341,0.910367,0.355693,-0.135533,0.925748,-0.352916,-0.03061,0.231269,0.972381,0.975982,0.184362,-0.11594,0.694266,0.717338,0.058412,0.712027,0.350871,-0.608173,-0.201483,0.259865,0.944365,-0.820185,0.572069,-0.001556,-0.322733,0.944334,0.063509,-0.922117,0.223151,0.315958], "skinIndices" : [], "skinWeights" : [], "morphTargets" : [], "bones" : [], "animations" : [], "colors" : [], "materials" : [ { "DbgColor": 15658734, "DbgIndex": 0, "DbgName": "default", "vertexColors": false } ] } Is it possible to use this content in code as a variable and add it to scane?
Here is the pattern to follow if you want to load a model by parsing a JSON data structure. Modify your mountain.json file and give your data structure a name. var mountain = { "metadata": { "formatVersion" : 3.1, "generatedBy" : "Blender 2.7 Exporter", ... etc ... } Include the following code in your source: <script src="mountain.js"></script> Now you can load your model like so: var loader = new THREE.JSONLoader(); var model = loader.parse( mountain ); mesh = new THREE.Mesh( model.geometry, model.materials[ 0 ] ); scene.add( mesh ); three.js r.70
Can't understand why my THREE.js object is partly transparent
I've created a solid (not transparent) object in blender and exported it with three.js blender plugin to get json data. And now when I'm adding it to three.js there are transparent areas of the object and I can't understand why cause I need it fully solid. Will appreciate any help with this. Here is javascript code: window.kristal_json = "metadata" : "formatVersion" : 3.1 "generatedBy" : "Blender 2.7 Exporter" "vertices" : 12 "faces" : 30 "normals" : 12 "colors" : 0 "uvs" : [10] "materials" : 1 "morphTargets" : 0 "bones" : 0 "scale" : 1.000000 "materials" : [ "DbgColor" : 15658734 "DbgIndex" : 0 "DbgName" : "Mat" "blending" : "NormalBlending" "colorAmbient" : [0.1694117690535153, 0.3545098119156034, 0.6400000190734865] "colorDiffuse" : [0.1694117690535153, 0.3545098119156034, 0.6400000190734865] "colorEmissive" : [0.0, 0.0, 0.0] "colorSpecular" : [0.5, 0.5, 0.5] "depthTest" : true "depthWrite" : true "shading" : "Lambert" "specularCoef" : 255 "transparency" : 1.0 "transparent" : false "vertexColors" : false ] "vertices" : [-1.0049,-0.55688,0.0199999,-0.904313,0.307844,0.02,-0.147116,-0.146545,0.952514,0.371123,0.528552,0.745001,0.364565,1.01051,0.0200001,0.957999,0.476094,0.0200001,0.78775,-0.343567,0.4682,-0.209197,-1.09765,0.0199999,0.882591,-0.615694,0.0199999,-0.147116,-0.146545,-0.912514,0.371123,0.528552,-0.705001,0.78775,-0.343567,-0.4282] "morphTargets" : [] "normals" : [-0.880306,-0.47438,0,0.462844,0.88641,0,-0.271249,-0.962493,0,-0.965972,0.258553,0,0.184973,0.982727,0,0.685232,0.728294,0,0.798334,-0.202094,-0.567248,0.798334,-0.202094,0.567248,0.218329,-0.76101,0.610859,0.261696,0.636799,0.725242,0.218329,-0.76101,-0.610859,0.261696,0.636799,-0.725242] "colors" : [] "uvs" : [[0.256514,1,0.228616,0.038417,0,0.594628,0.666692,0.948754,1,0.302325,0.746501,0,0.357698,0.026725,1,0,1,1,0,1]] "faces" : [42,0,8,7,0,0,1,2,0,1,2,42,0,1,4,0,0,3,4,0,3,4,42,4,5,6,0,4,5,6,4,5,6,42,0,6,8,0,0,6,1,0,6,1,42,0,4,6,0,0,4,6,0,4,6,42,8,0,7,0,1,0,2,1,0,2,42,8,11,0,0,1,6,0,1,7,0,42,4,1,0,0,4,3,0,4,3,0,42,11,5,4,0,6,5,4,7,5,4,42,11,4,0,0,6,4,0,7,4,0,42,2,1,0,0,7,8,9,8,3,0,42,1,3,2,0,7,8,9,3,9,8,42,3,4,1,0,7,8,9,9,4,3,42,5,4,3,0,7,8,9,5,4,9,42,5,6,3,0,7,8,9,5,6,9,42,3,2,6,0,7,8,9,9,8,6,42,0,7,2,0,7,8,9,0,2,8,42,6,2,7,0,7,8,9,6,8,2,42,8,7,6,0,7,8,9,1,2,6,42,5,6,8,0,7,8,9,5,6,1,42,1,9,0,0,8,7,9,3,10,0,42,10,1,9,0,8,7,9,11,3,10,42,4,10,1,0,8,7,9,4,11,3,42,4,5,10,0,8,7,9,4,5,11,42,11,5,10,0,8,7,9,7,5,11,42,9,10,11,0,8,7,9,10,11,7,42,7,0,9,0,8,7,9,2,0,10,42,9,11,7,0,8,7,9,10,7,2,42,7,8,11,0,8,7,9,2,1,7,42,11,5,8,0,8,7,9,7,5,1] "bones" : [] "skinIndices" : [] "skinWeights" : [] "animations" : [] initThreeJS = -> div = $('#canvas-scene') window.scene = new THREE.Scene() window.camera = new THREE.PerspectiveCamera(75, div.width()/div.height(), 0.1, 1000) camera.position.y = 2.5 camera.position.x = 1.5 window.renderer = new THREE.CanvasRenderer() renderer.setClearColor( '#F6FAFC' ); renderer.setSize(div.width(), div.height()) div.append(renderer.domElement) camera.position.z = 10 loader = new THREE.JSONLoader(true) parsed = loader.parse(kristal_json) kristal = new THREE.Mesh( parsed.geometry, new THREE.MeshLambertMaterial( { color: 0xF5FCFE, ambient: 0xF1F9FC, emissive: 0xDDEDF7} ) ) kristal.position.set(0,2,-1) kristal.scale.set(4,4,4) scene.add(kristal) window.light1 = new THREE.PointLight(0xffffff, 0.1) light1.position.set(-9.5, 7, 7) scene.add light1 render = -> requestAnimationFrame render if kristal kristal.rotation.y += 0.01 renderer.render scene, camera render() $ -> initThreeJS() P.S. Here is jsbin code of this http://jsbin.com/koxicuqavejo/1/
You need to set your material to THREE.DoubleSide krystal.material.side = THREE.DoubleSide;
Creating Markers from my JSON file
I am creating a map with markers from a json file, my issue is that I am unable to get the markers to show on the map. I can link a basic json file, but when I try with an array file I get no markers. My code is: <script src="js/mapping.js"></script> <script type="text/javascript"> (function () { window.onload = function () { // Creating a new map var map = new google.maps.Map(document.getElementById("map"), { center : new google.maps.LatLng(51.50746, -0.127594), zoom : 8, mapTypeId : google.maps.MapTypeId.ROADMAP }); // Creating a global infoBox object that will be reused by all markers infoBubble = new InfoBubble({ minWidth: 300, maxWidth: 400, minHeight: 300, maxHeight: 400, arrowSize: 50, arrowPosition: 50, arrowStyle: 2, borderRadius: 0, shadowStyle: 1, }); // end Creating a global infoBox object // Creating a global infoBox object tabs infoBubble.addTab('Details'); infoBubble.addTab('Info'); // end Creating a global infoBox object tabs // Custom Markers var markers = {}; var categoryIcons = { 1 : "images/liver_marker1.png", 2 : "images/liver_marker2.png", 3 : "images/liver_marker3.png", 4 : "images/liver_marker4.png", 5 : "images/liver_marker.png", 6 : "images/liver_marker6.png", 7 : "images/liver_marker.png" } // end Custom Markers // Looping through the JSON data for (var i = 0, length = json.length; i < length; i++) { var data = json[i], latLng = new google.maps.LatLng(data.Latitude, data.Longitude); // Creating a marker and putting it on the map var marker = new google.maps.Marker({ position : latLng, map : map, title : data.title, icon : categoryIcons[data.category] }); // Creating a closure to retain the correct data, notice how I pass the current data in the loop into the closure (marker, data) (function (marker, data) { // Attaching a click event to the current marker google.maps.event.addListener(marker, 'click', function(e) { //infoBubble.setContent('<b>'+data.description+'</b>'+'<br>'+data.name); infoBubble.updateTab(0, 'Details', data.deviceOwnerName); infoBubble.updateTab(1, 'Info', data.name); infoBubble.open(map, marker); map.panTo(loc); }); // end Attaching a click event to the current marker })(marker, data); // end Creating a closure } // end Looping through the JSON data } })(); google.maps.event.addDomListener(window, 'load', initialize); </script> And my json array file is: { "Device" : [{ "DeviceId" : "e889", "DeviceRef" : "Te889", "DeviceName" : null, "DeviceText" : "Operated by SE", "DeviceLocation" : { "Latitude" : "51.484804", "Longitude" : "-0.103226", "Address" : { "SubBuildingName" : null, "BuildingName" : null, "BuildingNumber" : null, "Thoroughfare" : null, "Street" : "Volcan Road North", "DoubleDependantLocality" : null, "DependantLocality" : null, "PostTown" : "Norwich", "PostCode" : "NR6 6AQ", "Country" : "gb" }, "LocationShortDescription" : null, "LocationLongDescription" : null }, "Connector" : [{ "ConnectorId" : "JEV01", "ConnectorType" : "JEVS G 105 (CHAdeMO)", "RatedOutputkW" : "50.00", "RatedOutputVoltage" : null, "RatedOutputCurrent" : null, "ChargeMethod" : "DC", "ChargeMode" : "1", "ChargePointStatus" : "In service", "TetheredCable" : "0", "Information" : null } ], "Controller" : { "OrganisationName" : "SE", "Website" : null, "TelephoneNo" : null, "ContactName" : null }, "DeviceOwner" : { "OrganisationName" : "Unknown", "Website" : null, "TelephoneNo" : null, "ContactName" : null }, "DeviceAccess" : { "RegularOpenings" : [{ "Days" : "Monday", "Hours" : { "From" : "08:00", "To" : "18:00" } }, { "Days" : "Tuesday", "Hours" : { "From" : "08:00", "To" : "18:00" } }, { "Days" : "Wednesday", "Hours" : { "From" : "08:00", "To" : "18:00" } }, { "Days" : "Thursday", "Hours" : { "From" : "08:00", "To" : "18:00" } }, { "Days" : "Friday", "Hours" : { "From" : "08:00", "To" : "18:00" } }, { "Days" : "Saturday", "Hours" : { "From" : "08:30", "To" : "05:00" } } ], "Open24Hours" : true }, "PaymentRequiredFlag" : false, "SubscriptionRequiredFlag" : true, "Accessible24Hours" : false, "PhysicalRestrictionFlag" : false, "PhysicalRestrictionText" : null, "OnStreetFlag" : false, "Bearing" : null } ]} I am trying to link to the Latitude and Longitude, but I am also looking to display the DeviceId. Any help would be appreciated. R
Latitude and Longitude are nested members within your JSON file. You cannot access them without first delving into the DeviceLocation member. I recommend you read this article (http://www.w3schools.com/json/) to understand how JSON works.
I had follow someone code samples and try apply to my HighChart program but I can't get it work at all
I had follow someone code samples, but I'm new to javascript and highcharts. In fact this program worked but only shows one month at a time, I want show all the months' data. Sorry for my English. Could you give me some advice thanks. $(document).ready(function () { var options = { chart : { renderTo : 'container', defaultSeriesType : 'column', rightMargin : 80 }, title : { text : 'the scholls' }, subtitle : { text : 'data for 2012 years' }, xAxis : { title : 'months', categories : [] }, yAxis : [{ min : 0, title : { text : 'students' } }, { linkedTo : 0, opposite : true } ], tooltip : { formatter : function () { return '<b>' + this.series.name + '</b><br/>' + this.x + 'Months: ' + this.y + ' students:'; } }, legend : { layout : 'vertical', align : 'right', verticalAlign : 'top', x : -10, y : 100, borderWidth : 0 }, series : [{ name : "students total", data : [] } ] }; //get the json files $.getJSON('http://localhost:3000/students/givemechart.json', function (data) { yData = options.series[0].data; //Array to store data for y column xData = options.xAxis.categories; //Array to store data for x column xDataObj = data[3]; //only can show one months yDataObj = data[3]; //only can show one totals // [[5, 2], [6, 3], [8, 2]] for (var key in xDataObj) { xData.push((xDataObj[key].month)); console.dir(xData); //chrome console only } for (var key in yDataObj) { yData.push((yDataObj[key].total)); console.dir(yData); //chrome console only } var chart = new Highcharts.Chart(options); }); }); This is one of my json files. [ { "student" : { "month" : 1, "total" : 24 } }, { "student" : { "month" : 2, "total" : 27 } }, { "student" : { "month" : 10, "total" : 96 } }, { "student" : { "month" : 11, "total" : 1088 } }, { "student" : { "month" : 12, "total" : 125 } } ]
Set Min and Max for Xaxis like this : xAxis : { title : 'months', categories : [], min: 1, max: 12 }