I want to populate some of the cooridnates what I get from the back end on mapbox map below is my sample json what I receive from backend
[
{
"model": "bike_parking_info.bikeparkinginfo",
"pk": 13561,
"fields": {
"start_station_id": 3276,
"start_station_name": "Marin Light Rail",
"start_station_latitude": "40.71458403535893",
"start_station_longitude": "-74.04281705617905",
"end_station_id": 3256,
"end_station_name": "Pier 40 - Hudson River Park",
"end_station_latitude": "40.7277140777778",
"end_station_longitude": "-74.01129573583603"
}
}
]
I have around 1200 objects to load from back end with coordinates
I am iterating it over below loop
let result = []
data.forEach(function (data1, index) {
//console.log(data1['fields']);
var jsonData={
// feature for Mapbox DC
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [
Number(data1['fields']['start_station_longitude']),
Number(data1['fields']['start_station_latitude']),
]
},
'properties': {
'title': data1['fields']['start_station_name']
}
}
result.push(jsonData);
export const mapDetails = state => state.getInfo.features;
this is how I am populating on UI
var map = new mapboxgl.Map({
container: mapContainer.current,
style: 'mapbox://styles/mapbox/light-v10',
center: [-96, 37.8],
zoom: 3
});
map.on('load', function () {
// Add an image to use as a custom marker
map.loadImage(
'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png',
function (error, image) {
if (error) throw error;
map.addImage('custom-marker', image);
// Add a GeoJSON source with 2 points
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': **mapDetails**
}
});
// Add a symbol layer
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker',
// get the title name from the source's "title" property
'text-field': ['get', 'title'],
'text-font': [
'Open Sans Semibold',
'Arial Unicode MS Bold'
],
'text-offset': [0, 1.25],
'text-anchor': 'top'
}
});
}
);
});
but I am getting below errors constantly
"Input data given to 'points' is not a valid GeoJSON object."
please help me out here what is going wrong ?
I got my fault I had to use useSelector to retrieve data back to my UI so had to make below changes
let dataToDisplay = useSelector(mapDetails);
Related
I am working on a react frontend for a woocommerce shop and I am currently trying to add an item to the cart with the selected option values ie size and color.
My current api call -
const AddToCart = async (id) => {
let config = {
method: "post",
url: "/wp-json/wc/store/v1/cart/add-item",
data: {
id : id,
quantity: 1,
attributes: [
{
color: color
},
{
size: size
}]
}
}
const resp = await axios(config).then((response) => {
console.log(response.data)
})
.catch((error) => {
console.log(error.response.data);
});
}
In the docs it says -
Chosen attributes (for variations) containing an array of objects with
keys attribute and value
However what I've tried is giving me this error -
code: "woocommerce_rest_variation_id_from_variation_data"
data: {status: 400}
message: "No matching variation found."
Example json response for single product -
{
"id": 933,
.......
"attributes": [
{
"id": 1,
"name": "Size",
"position": 0,
"visible": false,
"variation": true,
"options": [
"2XL",
"3XL",
"4XL",
"5XL",
"L",
"M",
"S",
"XL",
"XS"
]
}
],
"default_attributes": [],
"variations": [
936,
937,
938,
939,
940,
941,
942,
943,
944
],
......
You have to pass the data like this:
data: {
id: id,
quantity: 1,
variation: [
{
attribute: "color"
value: color,
},
{
attribute: "size"
value: size,
}
]
}
As per documentation, variation accepts the array of objects and objects should have keys attribute and value.
what's wrong with this
[{ attribute: 'color', value : selectedColor },{ attribute : 'size', value : selected }]
I want to plot multiple points in the same layer using mapbox and all these points will have their own property like color and label. And also upon clicking on an individual point, its should show a popup with the point's id.
Is this possible to achieve, as of now I have been looping over the points array and for each point I am creating a separate source and layer.
for(let i = 0; i < buildings.length; i++){
let mapSource = map.getSource(buildings[i].building_id);
if(!mapSource){
map.addSource(buildings[i].building_id, {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': buildings[i].centroid.coordinates
}
}
});
}
let mapLayer = map.getLayer(buildings[i].building_id);
if(!mapLayer){
map.addLayer({
'id': buildings[i].building_id,
'type': 'circle',
"paint": {
"circle-radius": 6,
"circle-color": SectionColors[buildings[i].section[0]]
},
"source": buildings[i].building_id
});
}
let mapLabel = map.getLayer(`${buildings[i].building_id}-label`);
if(!mapLabel){
map.addLayer({
'id': `${buildings[i].building_id}-label`,
'type': 'symbol',
'source': buildings[i].building_id,
'layout': {
'text-field': `${buildings[i].building_id}`,
'text-size': 14,
'text-variable-anchor': ["left"],
'text-radial-offset': 0.3,
'text-justify': 'auto',
},
'paint': {
'text-color': '#fff308'
}
});
}
map.on('click', buildings[i].building_id, function(e){
setPopUpTop(e.point.y+10);
setPopUpLeft(e.point.x+10);
setBuildingPopup(true);
setBuilding(buildings[i].building_id);
setInfoPanel(false);
});
map.on('mousemove', buildings[i].building_id, function(e){
map.getCanvas().style.cursor = 'pointer';
if(buildings[i].section){
let sectionBuildings = buildings.filter(item => item.section && item.section.includes(buildings[i].section[0]))
for(let j = 0; j < sectionBuildings.length; j++){
let mapLayer = map.getLayer(`${sectionBuildings[j].building_id}-borders-onHover`);
if(typeof mapLayer === 'undefined'){
map.addLayer({
'id': `${sectionBuildings[j].building_id}-borders-onHover`,
'type': 'circle',
'source': sectionBuildings[j].building_id,
"paint": {
"circle-radius": 8,
"circle-color": '#fff308'
},
});
}
}
}
});
map.on('mouseleave', buildings[i].building_id, function(e){
map.getCanvas().style.cursor = '';
if(buildings[i].section){
let sectionBuildings = buildings.filter(item => item.section && item.section.includes(buildings[i].section[0]))
for(let j = 0; j < sectionBuildings.length; j++){
let mapLayer = map.getLayer(`${sectionBuildings[j].building_id}-borders-onHover`);
if(typeof mapLayer !== 'undefined'){
map.removeLayer(`${sectionBuildings[j].building_id}-borders-onHover`);
}
}
}
});
}
When the number of points are few there is not much difference in performance, but when I am plotting a high number of points like 300-400, the performance is extremely slow.
The first thing you need to do is use a feature collection to have multiple points in one source:
map.addSource('multiple-points-source', {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"color": "#FFFFFF"
},
"geometry": {
"type": "Point",
"coordinates": [-46.757, 71.413]
}
},
{
"type": "Feature",
"properties": {
"color": "#000000"
},
"geometry": {
"type": "Point",
"coordinates": [-32.345, 72.816]
}
}
]
}
After that you can use data-driven styling to fill the circles with a color from the point feature's properties:
map.addLayer({
'id': 'multiple-points-layer',
'type': 'circle',
'source': 'multiple-points-source',
'layout': {
},
'paint': {
// use data-driven styling
'circle-color': ['get', 'color'],
},
});
Here is a working example using this technique: https://jsfiddle.net/132ygokd/2/
In an effort to create a treepanel, i configure it with a treestore whose AJAX proxy url receives json data i have no control of. But using Ext.data.reader.Json's transform property invokable before readRecords executes, gives an option to modify the passed raw (deserialized) data object from the AJAX proxy into a modified or a completely new data object. The transform config, gives the code snippet below:
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
// do some manipulation of the raw data object
return data;
},
scope: this
}
}
},
});
I would please like an example on how to go about modifying the return JSON object
[
{
"id": 3,
"attributes":
{},
"name": "user_one",
"login": "",
"email": "user_one#ats",
"phone": "0751223344",
"readonly": false,
"administrator": false,
"password": null
},
{
"id": 4,
"attributes":
{},
"name": "user_two",
"login": "",
"email": "user_two#ats",
"phone": "0751556677",
"readonly": false,
"administrator": false,
"password": null
}
]
into a JSON object fit for a treestore.
The hierarchical tree is to be rendered to show which user is under which admin using a condition administrator==true from the returned JSON, then a second AJAX request that returns that admin's users shown here.
[
{
"user_id": 3,
"admin_id": 1,
},
{
"user_id": 4,
"admin_id": 2,
}
]
Is the data nested at all? Otherwise why use a treepanel instead of a grid? To your question though, it'll depend on how you configure your treepanel but it would probably be something like this:
transform: {
fn: function(data) {
var treeRecords = Ext.Array.map(data, function(i){
return {
text: i.name,
leaf: true
//any other properties you want
}
});
var treeData = {
root: {
expanded: true,
children: treeRecords
}
};
return treeData;
},
scope: this
}
I am actually new to this highcharts . Been trying to render a line chart . I am facing issues while transforming the data returned by back-end to the data required by highcharts.
Can someone suggest me how to transform the below data object to the data required by line charts.Trying to plot a graph that compares current and previous values
Help would be appreaciated.
Object
{"data":
[
{"currentVal":3488,"prevVal":0,"timestamp":1554181200000},
{"currentVal":3453,"prevVal":3,"timestamp":1554481200000},
{"currentVal":3456,"prevVal":2,"timestamp":1554581200000}
]
}
As per the documnentaion the line charts data accepts the following structure.
"data": [
{
"name": "currentVal",
"data": [ 7,7,8]
},
{
"name": "prevVal",
"data": [1,6,7]
}
]
}
I would want the help in transforming the object that mentioned in the top
The simplest way to transform the object:
var obj = {
data: [{
"currentVal": 3488,
"prevVal": 3000,
"timestamp": 1554181200000
}, {
"currentVal": 3453,
"prevVal": 3123,
"timestamp": 1554481200000
}, {
"currentVal": 3456,
"prevVal": 3341,
"timestamp": 1554581200000
}]
};
Highcharts.chart('container', {
xAxis: {
type: 'datetime'
},
series: [{
name: "currentVal",
data: obj.data.map(elem => [
elem.timestamp, elem.currentVal
])
}, {
name: "prevVal",
data: obj.data.map(elem => [
elem.timestamp, elem.prevVal
])
}]
});
Demo:
https://jsfiddle.net/BlackLabel/y8efg4hx/1/
https://jsfiddle.net/BlackLabel/0fzjsuLw/1/
I am performing an Axios get call in a React Component to retrieve JSON info. That function is working great. Within the JSON is a label for various network ports, which are returning as an array in my axios call. These are ultimately going to be displayed as nodes on a d3 graph. My issue is that I need to output the data pulled from the get call into the following format:
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
So the full component for the graph to read is:
export const data = {
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
}
Here is the format of the Axios get I am using:
axios.get(`NetworkConstruct.json`)
.then(res => {
const names = res.data.items;
this.setState({ names });
});
Here is a sample output I am receiving (there are 11 of these):
{id: "5bc0860c-ece1-461c-bac0-b155a3cacd82", label: "80.107.0.212",
resourceTypeId: "tosca.resourceTypes.NetworkConstruct", productId:
"5bc0835c-6cfa-486e-8429-a59eaf4118bc", tenantId: "393fa8da-61fd-458c-80f9-
ce92d0ef0330", …}
The data has to be in this EXACT format or the graph won't read it. I'm guessing I'll need to do an initial map function but am stuck on how to arrange it. I cannot have any divs or quotes in my output. Is this doable? I have scoured the boards and Google for a couple of days and can't make this work yet.
Here is the object I am receiving from the GET request.
{
"id": "5bd2c6ef-6009-4b90-9156-62168f3c6293",
"resourceId": "5bd0ba82-2994-455d-8716-2adb5694d6f0",
"interface": "getGraph",
"inputs": {},
"outputs": {
"graph": {
"nodes": [
{
"id": "5bcdf06c-dd53-4335-840f-55a4b8d85a2d",
"name": "asw-lab9306b",
"ports": {
"GigabitEthernet3/0/8": "5bd1777f-0ab9-4552-962b-9e306ce378ab",
"GigabitEthernet2/0/15": "5bd1777e-119c-44e8-ba69-0d86a481c0f5",
"GigabitEthernet3/0/47": "5bd17783-be94-4aaf-8858-70e4eb3d02dc",
"GigabitEthernet2/0/13": "5bd17783-ed99-453f-a958-f764edaa8da8"
}
}
],
"links": [
{
"a": "5bd1a467-13f2-4294-a768-561187b278a8",
"z": "5bd17770-2e6c-4c37-93c8-44e3eb3db6dd",
"layer": "ETHERNET"
},
{
"a": "5bd1776e-c110-4086-87d6-a374ccee419a",
"z": "5bd17770-83ee-4e10-b5bb-19814f9f5dad",
"layer": "ETHERNET"
}
]
}
},
"state": "successful",
"reason": "",
"progress": [],
"providerData": {},
"createdAt": "2018-10-26T07:49:03.484Z",
"updatedAt": "2018-10-26T07:49:25.425Z",
"resourceStateConstraints": {},
"executionGroup": "lifecycle"
}
The info I need is the nodes ID. There are eleven of them in the full object.
You can map an array of objects to another array of objects in your format with Array.prototype.map(). Assuming that data is the list of objects from your response:
class Graph extends React.Component {
state = {
nodes: null,
};
componentDidMount() {
axios.get('the url').then(response => {
const nodes = response.data.outputs.graph.nodes;
this.setState({nodes});
});
}
render() {
const {nodes} = this.state;
if (!nodes) return 'Loading...'
return <TheD3ComponentYouUse nodes={nodes} />;
}
}