I'm relatively new to mongoose and nodejs. And i'm trying to hackup a quick server side script in nodejs.
I'm trying to retrieve data as array of objects from mongoDb using mongoose.
Here is what my Schema looks like -
var heatmapSchema = new Schema({
vuid: String
coordinates: [
{
x: Number,
y: Number,
c: Number,
timestamp: Number
}
]
}, {collection: collectionName} );
As you can see coordinates is an array of objects. I want to query mongoDb so I get an array of these coordinate objects, where c = 1 (c property in coordinate equals 1) i.e. -
[
{
x: 100,
y: 230,
c: 1,
timestamp: 1233312312
},
{
x: 120,
y: 240,
c: 1,
t: 1233313425
}
......
]
What would be the best way to achieve this in mongoose?
UPDATE
The closest I have gotten so far is using the below query -
heatmapModel.aggregate(
[
{
$unwind: '$coordinates'
},
{
$match: {
'coordinates.c': 1
}
},
{
$project: {
'_id': 0,
'coordinates.x': 1,
'coordinates.y': 1,
'coordinates.c': 1,
'coordinates.timestamp': 1
}
}
],
function (err, result) {
if (err) {
console.log(err);
process.exit(1);
}
console.log(result);
process.exit();
}
);
Which gives me the following output -
[ { coordinates: { x: 601, y: 165, c: 1, timestamp: 1438840800424 } },
{ coordinates: { x: 484, y: 192, c: 1, timestamp: 1438840801211 } },
{ coordinates: { x: 484, y: 192, c: 1, timestamp: 1438840801388 } },
{ coordinates: { x: 414, y: 394, c: 1, timestamp: 1438840802378 } },
.....
]
How do I get rid of the unwanted coordinates key in the json?
heatMap.find({'coordinates.c': 1}); should work.
Related
I am trying to map the data I get back from an API in this format:
data={[
{ x: 0, y: 0 },
{ x: 1, y: 1 },
{ x: 2, y: 2 },
{ x: 3, y: 3 },
{ x: 4, y: 4 },
]}
I have a get call then I map each of the items to give me an x , y value:
getCryptoChartData('histohour', selectedCrypto, 24, 1).then(
cryptoChartData => {
//const response = cryptoChartData.Data.map(item => item.close);
const data = cryptoChartData.Data.map(item => {
[
{
x: item.time,
y: item.close,
},
];
});
return this.setState({cryptoChartData: data});
},
);
However, I notice that the data array is set to undefined:
<SlideAreaChart
data={this.state.cryptoChartData}
/>
Am I setting the data array correctly with the mapping?
Yes, it seems the problem is in mapping. You just forget to return the generated object:
const data = cryptoChartData.Data.map(item => {
return {
x: item.time,
y: item.close,
};
});
or
const data = cryptoChartData.Data.map(item => ({
x: item.time,
y: item.close,
}));
Final code of getCryptoChartData method will look like:
getCryptoChartData('histohour', selectedCrypto, 24, 1)
.then(cryptoChartData => {
const data = cryptoChartData.Data.map(item => ({
x: item.time,
y: item.close,
}));
this.setState({ cryptoChartData: data });
});
I am using an Apexcharts treemap chart and want to apply different colors.
If type the data is of type 'a' I want it in one color and if it's of type 'b' I want another color.
My data:
const TreeData = [
{
data: [
{
x: 'Product 1',
y: 218,
type:'a'
},
{
x: 'Product 2',
y: 149,
type:'b'
}]
I've tried something like this:
colors: [function({ value, seriesIndex, w }) {
if (value < 55) {
return '#7E36AF'
} else {
return '#D9534F'
}
}, function({ value, seriesIndex, w }) {
if (value < 111) {
return '#7E36AF'
} else {
return '#D9534F'
}
}]
But I'm not able to get type value in the above function.
How do I use different colors?
To use different colors for each cell in a treemap, you can apply fillColor in the series itself.
series: [
{
data: [
{
x: 'New Delhi',
y: 218,
fillColor: '#3396F7'
},
{
x: 'Kolkata',
y: 149,
fillColor: '#EC4498'
},
{
x: 'Mumbai',
y: 184,
fillColor: '#61CF35'
}
]
}
]
I have a geoJSON file that I convert into vector.tiles using this npm package.
I use const tileIndex = geojsonvt(geoJSON). The geoJSON file has the following format and it gets converted without any error.
const geoJSON = {
type: 'FeatureCollection',
crs: {
type: 'name',
properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }
},
features: [
{
properties: [Object],
geometry: [Object],
type: 'Feature',
_id: '5ed7b221a61a4b2970433932'
},
... 1840 more items
]
}
The result (geoJSON vector-tiles) that I get after conversion is following -
const tiles = {
options: {},
tiles: {
'0': {
features: [Array],
numPoints: 540529,
numSimplified: 3,
numFeatures: 1940,
source: null,
x: 0,
y: 0,
z: 0,
transformed: false,
minX: 0.5162953202777778,
minY: 0.316725863688461,
maxX: 0.5338655772222223,
maxY: 0.34955196703359503
},
'1': { ... }
},
tileCoords: [
{ z: 0, x: 0, y: 0 }, { z: 1, x: 1, y: 1 },
{ z: 1, x: 1, y: 0 }, { z: 2, x: 3, y: 1 },
{ z: 2, x: 3, y: 0 }, { z: 2, x: 2, y: 1 },
{ z: 3, x: 5, y: 3 }, { z: 3, x: 5, y: 2 },
{ z: 3, x: 4, y: 3 }, { z: 3, x: 4, y: 2 },
{ z: 4, x: 9, y: 5 }, { z: 4, x: 9, y: 4 },
{ z: 4, x: 8, y: 5 }, { z: 5, x: 17, y: 11 },
{ z: 5, x: 17, y: 10 }, { z: 5, x: 16, y: 11 },
{ z: 5, x: 16, y: 10 }, { z: 4, x: 8, y: 4 },
{ z: 2, x: 2, y: 0 }, { z: 1, x: 0, y: 1 },
{ z: 1, x: 0, y: 0 }
]
}
After converting a huge geoJSON file with 5000 layers into vector tiles, I am sending this data to the client-side wherein I render Map using React.js and Mapbox*. I use following to render the map but I have not been able to figure out what I am doing wrong. The error that I get says error: layers.jsx-layer-0: layer "jsx-layer-0" must specify a "source-layer"
<Source type="vector" tiles={data.tiles} >
<Layer {...dataLayer}/>
</Source>
I went through the documentation of Mapbox for the same but I'm unable to find what I am doing wrong. Any help would be of great help. Thank you very much.
react-mapbox-gl is in many places just a wrapper around mapbox-gl, and if you look at the documentation there:
https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/#tiled-sources
You will see that the "tiles" property is only for url sources, where as the "url" property can be used to load a file with tiles:
"url": "http://api.example.com/tilejson.json"
The docs indicate that the source-layer is required field for vector layers.
That said, it certainly opaque as to how this works in a declarative api. Based on example, you might try this to see if it works -
...
const url = 'mapbox://mapbox.mapbox-terrain-v2'
const source = 'my-source';
<Source id={{source}} name={{source}} type="vector" url={url} tiles={data.tiles} >
<Layer source={{source}} {...dataLayer}/>
</Source>
...
rendering a layer with it source so you need to referrer to source id in layer + you need to add a source-layer prop like this:
<Source id='contours' type='vector' url='mapbox://mapbox.mapbox-terrain-v2' tileJsonSource={data.tiles}/>
<Layer
id='contours'
type='line'
source='contours'
source-layer='contour'
paint={{
'line-color': '#877b59',
'line-width': 1
}}
/>
</MapGL>;
The code work perfectly in the vega online editor. But there are warnings in the console while using in react component and the X-axis is not rendering in the output.
import React from 'react';
import { Vega } from 'react-vega';
import { VisualizationSpec } from 'vega-embed';
export function LineGraph() {
const specs: VisualizationSpec = {
$schema: 'https://vega.github.io/schema/vega/v5.json',
description: 'A basic line chart example.',
width: 500,
height: 200,
padding: 5,
signals: [],
data: [
{
name: 'table',
format: {
parse: { x: 'date' },
},
},
],
scales: [
{
name: 'x',
type: 'time',
range: 'width',
domain: { data: 'table', field: 'x' },
},
{
name: 'y',
type: 'linear',
range: 'height',
nice: true,
zero: true,
domain: { data: 'table', field: 'y' },
},
],
axes: [
{ orient: 'bottom', scale: 'x' },
{ orient: 'left', scale: 'y' },
],
marks: [
{
type: 'line',
from: { data: 'table' },
encode: {
enter: {
x: { scale: 'x', field: 'x' },
y: { scale: 'y', field: 'y' },
stroke: { value: 'red' },
strokeWidth: { value: 2 },
},
},
},
],
};
const data: any = {
table: [
{ x: '01-08-2020', y: 28, c: 0 },
{ x: '01-03-2020', y: 43, c: 0 },
{ x: '01-01-2020', y: 81, c: 0 },
{ x: '01-09-2020', y: 19, c: 0 },
{ x: '01-02-2020', y: 52, c: 0 },
{ x: '01-04-2020', y: 24, c: 0 },
{ x: '01-07-2020', y: 87, c: 0 },
{ x: '01-07-2020', y: 17, c: 0 },
{ x: '01-08-2020', y: 68, c: 0 },
{ x: '01-09-2020', y: 49, c: 0 },
],
};
const signalListeners = {};
return (
<div>
<Vega data={data} signalListeners={signalListeners} spec={specs} />
</div>
);
}
Warnings:
WARN Infinite extent for field "y": [Infinity, -Infinity]
WARN Infinite extent for field "x": [Infinity, -Infinity]
How to define the extent in vega?
There are two parts to this error - the console warning, and the lack of rendering.
The console warning gets thrown in digest cycles when the data hasn't yet been injected into the spec; not ideal, but AFAIK can be ignored.
The rendering looks to be due to an error in how react-vega handles the date parsing. Instead of passing in date as strings, first convert them to Date objects, then pass in the modified data to the Vega component.
I am trying to get the max value of the x axis and set an annotation just at the end:
y: chart.xAxis[0].max-1
What is the right syntax to get it working in react? See a live demo here.
You can not use values from the chart in options. You should add your annotations dynamically in addAnnotation method:
chart: {
events: {
load: function(){
const chart = this;
chart.addAnnotation({
labels: [
{
point: {
x: 3,
y: chart.xAxis[0].max - 1,
xAxis: 0,
yAxis: 0
},
text: "x: {x}<br/>y: {y}"
},
{
point: {
x: 0,
y: 0
},
text: "x: {point.plotX} px<br/>y: {point.plotY} px"
},
{
point: {
x: 5,
y: 100,
xAxis: 0
},
text: "x: {x}<br/>y: {point.plotY} px"
}
],
labelOptions: {
x: 40,
y: -10
}
})
}
}
}
Live demo: https://codesandbox.io/s/537kz8xwyx