Combining Column charts and line charts with the same same data in the same container(Highcharts) - angularjs

I want to build a combination chart with a column chart with multiple series and a line chart. Problem is that I am getting High charts data from nested JSON response. For that I initialized array and that array is giving in series in plotoptions highcharts as you can see in the below code.
My code is like this:
var crime_data=[];
for(var i=0;i<result.themes.length;i++){
var crime={};
var test2 = result.themes[i];
var test = test2[Object.keys(test2)];
crime.name = Object.keys(result.themes[i]);
crime.data = [];
for(var k=0;k<test.yearTheme.length;k++){
var test3=test.yearTheme[k];
var test5=test3.individualValueVariable;
for(var j=0;j<test5.length;j++){
crime.data.push(test5[j].count);
};
};
crime_data.push(crime);
};
var crimeChart = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type:'column'
},
title: {
text: 'Crime'
},
xAxis: {
categories: month,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Count'
}
},
credits: {
enabled: false
},
tooltip: {
shared: true,
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
depth: 25,
allowPointSelect: true,
cursor: 'pointer',
point: {
},
}
},
series: crime_data
});
This is Column chart I am getting when i write chart type column.
This is my Line Chart I am getting when i changed type column to spline in chart in highcharts.
And this is my JSON data(Highcharts data):
{
"boundaries": {
"boundary": [
{
"boundaryId": "55083021003",
"boundaryType": "USA_CITY",
"boundaryRef": "C1"
}
]
},
"themes": [
{
"AssaultCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [
{
"name": "2013 Assault Crime",
"description": "Assault Crime for 2013",
"count": 18901
},
{
"name": "2014 Assault Crime",
"description": "Assault Crime for 2014",
"count": 17707
}
]
}
},
{
"BurglaryCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [
{
"name": "2013 Burglary Crime",
"description": "Burglary Crime for 2013",
"count": 17743
},
{
"name": "2014 Burglary Crime",
"description": "Burglary Crime for 2014",
"count": 14242
}
]
}
}
]
}
I want to combine both of them in the same container with same data.The problem is in how to tell highcharts multiple series should be represented with line and with column type with same data.For this when i write series:[{ data: crime_data ,type: spline }] instead of series:crime_data In that case I am not getting Highcharts data. Can anyone Please help me how should i do this.Please suggest me.

Pass your data, like below format. add type of chart in each data series;
Here i replaced type value but with same data.
[{
type: 'line',
name: 'AssaultCrimeTheme',
data: [3, 2, 1, 3, 4]
}, {
type: 'line',
name: 'BurglaryCrimeTheme',
data: [2, 3, 5, 7, 6]
}, {
type: 'column',
name: 'AssaultCrimeTheme',
data: [3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'BurglaryCrimeTheme',
data: [2, 3, 5, 7, 6]
},]
Here is fiddle for more details.

Here is a complete example using your data.
const json = {
"boundaries": {
"boundary": [{
"boundaryId": "55083021003",
"boundaryType": "USA_CITY",
"boundaryRef": "C1"
}]
},
"themes": [{
"AssaultCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [{
"name": "2013 Assault Crime",
"description": "Assault Crime for 2013",
"count": 18901
}, {
"name": "2014 Assault Crime",
"description": "Assault Crime for 2014",
"count": 17707
}]
}
}, {
"BurglaryCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [{
"name": "2013 Burglary Crime",
"description": "Burglary Crime for 2013",
"count": 17743
}, {
"name": "2014 Burglary Crime",
"description": "Burglary Crime for 2014",
"count": 14242
}]
}
}]
}
// Create categories object in order filter duplicates
const cats = {}
const series = json.themes.map((o) => {
const key = Object.keys(o)[0]
return {
name: key,
data: o[key].individualValueVariable.map((o) => {
cats[o.name] = 1
return { category: o.name, y: o.count }
})
}
})
// Convert categories object to array
const categories = Object.keys(cats)
// Chart options
const options = {
chart: {type: 'column'},
xAxis: {categories: categories},
series: series
}
// Create chart
const chart = Highcharts.chart('container', options)
console.log(series, categories)
Live example: https://jsfiddle.net/Lo323gq3/
Output below:

Related

Creating an object dynamically - React/Typescript

I am getting an object from the backend with the following structure:
"periods": [
{
"id": 12,
"schemes": [
{
"id": 123,
"parts": [
{
"id": 1234,
"facts": {
"id": 21,
"basis": {
"id": 12344,
"amount": 10
},
"factor": {
"id": 1234,
"prop": 12
}
},
"deduction": {
"id": 133
},
"date": "22-10-2022",
"years": 12
},
{... more parts}
]
},
{... more schemes}
]
},
{... more periods}
]
I am changing the data and sending it back via a PATCH. The payload expects the id, the period.id, and an object with the same structure as above but only with the changed fields.
One example is, that I am changing the field amount. Then I need to know which part, which scheme and which period I am changing the amount in. And the object I am sending back should look something like this (the date should always be included):
{
"id": 22,
"schemes": [
{
"id": 43,
"parts": [
{
"id": 32,
"facts": {
"id": 77,
"basis": {
"id": 232,
"amount": 134 // CHANGING THIS
}
},
"date": "22-10-2022",
},
{... more parts}
]
},
{... more schemes}
]
}
At the moment I am solving it by taking the whole object from the backend and filtering out the one with the id and date (using the lodash filter function) which matches the one that changed, then creating a new object with those and the changed fields. Here is a snippet from my function:
if (name === "basis") {
const [period]: Period[] = _.filter(periods, {
schemes: [
{
parts: [
{
facts: {
id: data?.facts?.id,
basis: {
id: data?.facts?.basis?.id,
},
},
date: data?.date,
},
],
},
],
});
request = {
id: period?.id,
schemes: [
{
id: 2,
parts: [
{
id: data?.id,
facts: {
id: data?.facts?.id,
basis: {
id: data?.facts?.basis?.id,
amount: data?.facts?.basis?.amount,
},
},
date: data?.date,
},
],
},
],
};
}
return request;
I have an array of the keys of the changed fields in the state. And also a part-object with all the data and not only the changed data. My question is how I can create an object with the structure as above but only with changed data dynamically and not manually like I am doing right now?

How to show bindPopUp() in Leaflet with angularjs

I am trying to use leaflet with angularjs. But I'm having trouble displaying array data table from "sensor" in "bindPopUp" content.
Can anyone help me how to display the data?
This is the array I'm using
$scope.oAllMarker = function() {
$scope.location = [{
"loc": "Jodhpur",
"lat": 26.28,
"long": 73.02,
"sensor": [{
"v1": 11
}, {
"v2": 12
}, {
"v3": 13
}]
},
{
"loc": "Bikaner",
"lat": 28.0229,
"long": 73.3119,
"sensor": [{
"v1": 21
}, {
"v2": 22
}, {
"v3": 23
}]
},
{
"loc": "Churu",
"lat": 28.3254,
"long": 74.4057,
"sensor": [{
"v1": 31
}, {
"v2": 32
}, {
"v3": 33
}]
}
];
And this is the angularjs and leaflet code i am using
angular.forEach($scope.location, function(item, key) {
$scope.dataIcon = L.icon({
iconUrl: "{{ url('image/storm.png') }}",
iconSize: [38, 45]
});
$scope.content = String('Table:Array sensor (v1,v2,v3)');
marker = new L.marker([parseFloat(item.lat), parseFloat(item.long)], {
icon: $scope.dataIcon
}).addTo($scope.map).bindPopup($scope.content);
});
}

How to Update Array dict Elements in mongodb based on another field

How can I update a value in a document based on applying functions to another field (which is in a different embedded document)?
With the sample data below, I want to
get the col field for the farm having id 12
multiply that by 0.025
add the current value of the statistic.crypt field
ensure the value is a double by converting it with $toDouble
store the result back into statistic.crypt
data:
{
"_id": {
"$oid": "6128c238c144326c57444227"
},
"statistic": {
"balance": 112570,
"diamond": 14,
"exp": 862.5,
"lvl": 76,
"mn_exp": 2.5,
"lvl_mn_exp": 15,
"coll_ms": 8047,
"all_exp": 67057.8,
"rating": 0,
"crypt": 0
},
"inventory": {
"farm": [{
"id": 12,
"col": 100,
"currency": "diamond",
"cost": 2,
"date": "2021-09-02 18:58:39"
}, {
"id": 14,
"col": 1,
"currency": "diamond",
"cost": 2,
"date": "2021-09-02 16:57:08"
}],
"items": []
},
...
}
My initial attempt is:
self.collection
.update_many({"inventory.farm.id": 12}, [{
"$set": {
"test": {
'$toDouble': {
"$sum": [
{'$multiply':["$inventory.farm.$[].col", 0.025]},
'$test'
]
}
} }
},])
This does not work as it applies to test rather than statistic.crypt, and I cannot figure out how to modify it to apply to statistic.crypt.
A field can be updated based on another in the following stages:
add a field containing the farm
set statistic.crypt to the result of the mathematical expression (applied to the newly embedded farm)
remove extra fields
In code:
self.collection.update_many({"inventory.farm.id": 12 }, [
{
$addFields: {
hh: {
$filter: {
input: "$inventory.farm",
as: "z",
cond: { $eq: ["$$z.id", 12] },
},
},
},
},
{
$set: {
"statistic.crypt": {
$toDouble: {
$sum: [
{
$multiply: [{ $first: "$hh.col" }, 0.025],
},
"statistic.crypt",
],
},
},
},
},
{
$project: {
id_pr: 1,
id_server: 1,
role: 1,
warns: 1,
id_clan: 1,
statistic: 1,
design: 1,
date: 1,
inventory: 1,
voice: 1,
},
},)

How to loop array after process groupBy in React-Native

i want to grouping data JSON (One JSON) base on region. and the json after grouping like in (Two JSON). and i use the two JSON for show data (Result JSON). so, how to add loop base on region after grouping, because actually i want to show data in front end like (Result JSON):
==>One JSON
data:[
{id:1,
status: "active",
dataDetail: {
id: 5,
name: tes 1,
region: aaa,
}
},
{id:2,
status: "active",
dataDetail: {
id: 8,
name: tes 2,
region: bbb,
}
},
{id:3,
status: "active",
dataDetail: {
id: 8,
name: tes 3,
region: aaa,
}
}
]
==> Two JSON
aaa: [
{id:1,
status: "active",
dataDetail: {
id: 5,
name: tes 1,
region: aaa,
}
},
{id:3,
status: "active",
dataDetail: {
id: 8,
name: tes 3,
region: aaa,
}
}
],
bbb: [
{id:2,
status: "active",
dataDetail: {
id: 8,
name: tes 2,
region: bbb,
}
},
]
==> Result JSON
aaa:
1
3
bbb:
2
thanks
Using Lodash:
const jsonTwo = _.groupBy(data, instance => instance.dataDetail.region);
const resultJson = _.mapValues(jsonTwo, regionInstances => regionInstances.map(instance => instance.id));
Using plain javascript reduce functions:
const jsonTwo = data.reduce((accumulator, instance) => {
if(!accumulator[instance.dataDetail.region]) {
accumulator[instance.dataDetail.region] = [];
}
accumulator[instance.dataDetail.region].push(instance)
return accumulator;
},{});
const resultJson = data.reduce((accumulator, instance) => {
if(!accumulator[instance.dataDetail.region]) {
accumulator[instance.dataDetail.region] = [];
}
accumulator[instance.dataDetail.region].push(instance.id)
return accumulator;
},{});
var data =
[
{
"id": 1,
"status": "active",
"dataDetail": {
"id": 5,
"name": "tes 1",
"region": "aaa"
}
},
{
"id": 2,
"status": "active",
"dataDetail": {
"id": 8,
"name": "tes 2",
"region": "bbb"
}
},
{
"id": 3,
"status": "active",
"dataDetail": {
"id": 8,
"name": "tes 3",
"region": "aaa"
}
}
];
groups =_.chain(data).groupBy('dataDetail.region');
keys = groups.map( (value, key) => key);
values = groups.map( (value, key) => _.map(value, 'id'));
result = _.zipObject(keys, values);

mapbox-gl.js with PGRestAPI vector tile(pbf)

I have own vector tile from PGRestAPI, url like below
"http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"
and I try use mapbox-gl.js to render the map, but nothing display.
I am doing wrong? thx
var style = {
"version": 8,
"sources": {
"countries": {
"type": "vector",
"tiles": ["http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"],
"maxzoom": 6
}
},
"glyphs": location.origin+location.pathname+"font/{fontstack}/{range}.pbf",
"layers": [{
"id": "background",
"type": "background",
"paint": {
"background-color": "#ddeeff"
}
},{
"id": "country-glow-outer",
"type": "line",
"source": "countries",
"source-layer": "country",
"layout": {
"line-join":"round"
}
}]
};
var init_lat = 1.3552799//42.299228067198634;
var init_lng = 103.6945413;//-83.69717033229782;
mapboxgl.accessToken = 'mapbox-token';
var map = new mapboxgl.Map({
container: 'map',
style: style,
center: [init_lng,init_lat],
zoom: 15
});
edit 1:
after debug mapbox-gl-js code, now can see several circles. I modify the style, the source-layer name from pbf must be correct.
but not display all the points, it seems filtered?
var style = {
"version": 8,
"sources": {
"cleantech": {
"type": "vector",
// "url": "mapbox://map-id"
// "url": "http://tileserver.com/layer.json",
"tiles": ["http://192.168.1.4:3001/services/postgis/cleantech2/geom/vector-tiles/{z}/{x}/{y}.pbf"],
"maxzoom": 6
}
},
"glyphs": location.origin+location.pathname+"font/{fontstack}/{range}.pbf",
"layers": [{
"id": "cleantech2_geom_id",
"type": "circle",
'source': 'cleantech',
'layout': {
'visibility': 'visible'
},
'paint': {
'circle-radius': 8,
'circle-color': 'rgba(55,148,179,1)'
},
'source-layer': 'cleantech2_geom'
}]
};
edit 2:
change the maxzoom to 22, all data displayed. lets drink!

Resources