MongoDb select objects from an array where object property matches coondition - arrays

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

Data Array Undefined React Native

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 });
});

How to use different colors in Apex charts with a condition?

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'
}
]
}
]

Rendering vector-tiles using Mapbox using react-mapbox-gl

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>;

React-Vega - WARN Infinite extent for field "x": [Infinity, -Infinity]

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.

Get max of x axis in highcharts using react

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

Resources