How to get polygon data from map in angular2-google-maps? - angular2-google-maps

I working on this example:
#Component({
selector: 'my-app',
styles: [`
.sebm-google-map-container {
height: 300px;
}
`],
template: `
<sebm-google-map
[latitude]="lat"
[longitude]="lng"
[zoom]="zoom"
[disableDefaultUI]="false"
[zoomControl]="false">
<sebm-map-polygon
[paths]="paths"
[editable]="true"
[draggable]="true"
(polyClick)="click(event)"
(polyDblClick)="delete(event)">
</sebm-map-polygon>
</sebm-google-map>
`})
export class App {
zoom: number = 8;
paths : Array<LatLngLiteral>;
lat: number = 51.673858;
lng: number = 7.815982;
click(event: any){
console.log(event);
}
delete(event: any){
console.log(event);
}
paths: Array<LatLngLiteral> = [
{ lat: 51.373858, lng: 7.815982 },
{ lat: 51.673858, lng: 7.215982 },
{ lat: 51.373858, lng: 7.895982 }
];
}
http://plnkr.co/edit/8SuDfG6BD0HubpLHqHc8?p=preview
but I want to get all polygon data when I click button "save" (in my project).
How to get all polygon data from map?

Related

How to Pass data from api into pie chart with angular

I would like to pass the output of an API in a piechart canvas with angular but I could not achieve any result, the API is consumed but I have a problem associating it with the piechart (datapoints)
the code just below.
app.component.ts
import { Component, OnInit } from '#angular/core';
import { EmailValidator } from '#angular/forms';
import { Router, NavigationEnd } from '#angular/router';
import { ApiService } from './api.service';
import { ApistatService } from './apistat.service';
import * as CanvasJS from './canvasjs.min';
//var CanvasJS = require('./canvasjs.min');
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
elements: any[];
constructor(
private apistatService: ApistatService
) {
this.elements = [];
}
ngOnInit() {
let chart = new CanvasJS.Chart("chartContainer", {
theme: "light2",
animationEnabled: true,
exportEnabled: true,
title:{
text: "Monthly Expense"
},
data: [{
type: "pie",
showInLegend: true,
toolTipContent: "<b>{elements.total}</b>: ${y} (#status)",
indexLabel: "{name} - #percent%",
dataPoints: [
{ y: 120, name: "Insurance" },
{ y: 300, name: "Traveling" },
{ y: 800, name: "Housing" },
{ y: 150, name: "Education" },
{ y: 150, name: "Shopping"},
{ y: 250, name: "Others" }
]
}]
});
this.apistatService.getData().subscribe((data:any) => {
if(data.status === 200) {
console.log(data.response);
this.elements = data.response;
}
})
chart.render();
}
}
app.component.html
<div id="chartContainer" style="height: 370px; width: 100%; margin-left:auto;margin-right:auto;">
</div>
To consume API data in pie chart you should just set data from API to dataPoints array just make sure your API data has same formatting as currently available inside dataPoints array which you are passing in data array while rendering chart, and it will work.

how to handle multiple request keys with the same value?

For this project, I'm building out models and passing in values from the body of a POST request. I want to understand how I should be declaring the models.
Sample of JSON which I want to be posted to MongoDB.
{
"signageId": "5cd857c4965f863b7c88d24a",
"parameters": {
"imageURL": "url.com",
"page": {
"pageHeight": "100", //want to change to "height"
"pageWidth": "100" //want to change to "width"
},
"density": {
"height": "300",
"width": "300"
}
}
}
I want to name pageHeight and pageWidth just "height" and "width" within the JSON, like I have done for the density segment, but I'm having difficulties knowing how to declare the models and grab the values from the request.
Model I'm using:
const ObjectSchema = new Schema({
signageId: {
type: String,
require: true
}
parameters: {
imageURL: {
type: String,
require: true
}
},
page: {
pageHeight: {
type: String
},
pageWidth: {
type: String
}
},
density: {
height: {
type: String
},
width: {
type: String
}
}
}
});
Post router
router.post('/', (req, res) =>{
const object = new Objects({
signageId: req.body.signageId,
imageURL: req.body.imageURL,
page: req.body.page,
pageHeight: req.body.pageHeight,
pageWidth: req.body.pageWidth,
density: req.body.density,
height: req.body.height,
width: req.body.width
});
try {
object.save();
res.json({object});
}
catch (err) {
res.json({message: err});
}
});
Your new object should be something like this.
const newObject = new Objects({
signageId: req.body.signageId,
parameters: {
imageURL: req.body.imageURL,
page: {
height: req.body.pageHeight,
width: req.body.pageWidth,
},
density: {
height: req.body.height,
width: req.body.width,
}
}
});
Notes:
1. Give your mongoose schema another name, in order to avoid javascript conflicts.
2. You can use height and width properties for different objects.
page: {
height: {
type: String
},
width: {
type: String
}
},
density: {
height: {
type: String
},
width: {
type: String
}
}
3. the model properties should be required, not require

Link:dbclick event with vertex Adding set to true [Jointjs] [Rappid]

I am unable to get Link:dbclick event on double click of link with vertexAdding: set to true.
with Vertex Adding set to false the dbclick event works fine.
i am using link:pointerup to add Tool view to link like this::
this.paper.on('link:pointerup', (linkView) => {
var tools;
var ns = joint.linkTools;
var toolsView = new joint.dia.ToolsView({
name: 'link:pointerup',
tools: [
new ns.Vertices(),
new ns.Vertices({ vertexAdding: true}),
new ns.Remove({ focusOpacity: 0.5,
distance: 5,
offset: 10}),
new ns.TargetArrowhead(),
new ns.Segments(),
new ns.Boundary({ padding: 10 }),
]
});
joint.ui.Halo.clear(this.paper);
joint.ui.FreeTransform.clear(this.paper);
this.paper.removeTools();
linkView.addTools(toolsView);
});
For Link Creation:::
export class Link2 extends joint.shapes.standard.Link {
defaults() {
return joint.util.defaultsDeep({
router: {
name: 'normal',
},
connector: {
name: 'normal',
},
labels: [],
attrs: {
line: {
stroke: '#284f96',
strokeDasharray: '0',
strokeWidth: 1,
fill: 'none',
sourceMarker: {
d: 'M 0 0 0 0',
fill: {
type: 'color-palette',
group: 'marker-source',
when: { ne: { 'attrs/line/sourceMarker/d': 'M 0 0 0 0' } },
index: 2
},
},
targetMarker: {
d: ' M 0 -3 -6 0 0 3 z',
},
}
}
}, joint.shapes.standard.Link.prototype.defaults);
}
defaultLabel = {
attrs: {
rect: {
fill: '#ffffff',
stroke: '#8f8f8f',
strokeWidth: 2,
refWidth: 10,
refHeight: 10,
refX: 0,
refY: 0
}
}
};
getMarkerWidth(type: any) {
const d = (type === 'source') ? this.attr('line/sourceMarker/d') : this.attr('line/targetMarker/d');
console.log("marker width", this.getDataWidth(d));
return this.getDataWidth(d);
}
getDataWidth = memoize(function (d: any) {
return (new joint.g.Rect(d)).bbox().width;
});
static connectionPoint(line: any, view: any, magnet: any, opt: any, type: any, linkView: any) {
// const markerWidth = linkView.model.getMarkerWidth(type);
opt = { offset: 5, stroke: true };
// connection point for UML shapes lies on the root group containg all the shapes components
const modelType = view.model.get('type');
if (modelType.indexOf('uml') === 0) opt.selector = 'root';
// taking the border stroke-width into account
if (modelType === 'standard.InscribedImage') opt.selector = 'border';
return joint.connectionPoints.boundary.call(this, line, view, magnet, opt, type, linkView);
}
}
and i am using following code to get double click event on Link:::
this.rappid.paper.on(
"link:pointerdblclick", (linkView) => {
// linkView.model.attr("priority",0);
console.log("linkview", linkView);
// this.currentLink = linkView
this.setState({ modalView: "lableModal", visible: true, currentLink: linkView });
});

Adding joint.dia.ToolsView to link, Unable to get double click event. [JointJS] [RappidJS]

After adding tool view to links on single click over link I am unable to get the link's double click event. I am using react to develop a interactive graph application using RappidJS library. Please help.
i am using link:pointerup to add Tool view to link like this::
this.paper.on('link:pointerup', (linkView) => {
var tools;
var ns = joint.linkTools;
var toolsView = new joint.dia.ToolsView({
name: 'link:pointerup',
tools: [
new ns.Vertices(),
new ns.Remove({ focusOpacity: 0.5,
distance: 5,
offset: 10}),
new ns.TargetArrowhead(),
new ns.Segments(),
new ns.Boundary({ padding: 10 }),
]
});
joint.ui.Halo.clear(this.paper);
joint.ui.FreeTransform.clear(this.paper);
this.paper.removeTools();
linkView.addTools(toolsView);
});
For Link Creation:::
export class Link2 extends joint.shapes.standard.Link {
defaults() {
return joint.util.defaultsDeep({
router: {
name: 'normal',
},
connector: {
name: 'normal',
},
labels: [],
attrs: {
line: {
stroke: '#284f96',
strokeDasharray: '0',
strokeWidth: 1,
fill: 'none',
sourceMarker: {
d: 'M 0 0 0 0',
fill: {
type: 'color-palette',
group: 'marker-source',
when: { ne: { 'attrs/line/sourceMarker/d': 'M 0 0 0 0' } },
index: 2
},
},
targetMarker: {
d: ' M 0 -3 -6 0 0 3 z',
},
}
}
}, joint.shapes.standard.Link.prototype.defaults);
}
defaultLabel = {
attrs: {
rect: {
fill: '#ffffff',
stroke: '#8f8f8f',
strokeWidth: 2,
refWidth: 10,
refHeight: 10,
refX: 0,
refY: 0
}
}
};
getMarkerWidth(type: any) {
const d = (type === 'source') ? this.attr('line/sourceMarker/d') : this.attr('line/targetMarker/d');
console.log("marker width", this.getDataWidth(d));
return this.getDataWidth(d);
}
getDataWidth = memoize(function (d: any) {
return (new joint.g.Rect(d)).bbox().width;
});
static connectionPoint(line: any, view: any, magnet: any, opt: any, type: any, linkView: any) {
// const markerWidth = linkView.model.getMarkerWidth(type);
opt = { offset: 5, stroke: true };
// connection point for UML shapes lies on the root group containg all the shapes components
const modelType = view.model.get('type');
if (modelType.indexOf('uml') === 0) opt.selector = 'root';
// taking the border stroke-width into account
if (modelType === 'standard.InscribedImage') opt.selector = 'border';
return joint.connectionPoints.boundary.call(this, line, view, magnet, opt, type, linkView);
}
}
and i am using following code to get double click event on Link:::
this.rappid.paper.on(
"link:pointerdblclick", (linkView) => {
// linkView.model.attr("priority",0);
console.log("linkview", linkView);
// this.currentLink = linkView
this.setState({ modalView: "lableModal", visible: true, currentLink: linkView });
});

Extracting properties from material-ui's GridList

I only started studying React a few days ago so please forgive me if this question sounds really stupid.
In this work assignment, I have to implement a 'Like' system using material-ui's GridList. There will be eight pictures in total where users can like them by clicking on the like button. In my current code, users can click on the like button but all the like buttons will be affected instead of just one. Furthermore, the number of likes does not increase.
So my question is, how can I change the number of likes when a user clicks the 'Like' button and make sure only 1 button is affected? I have tried props and even lodash but I just cannot seem to figure out the problem. Below is my entire code for the GridList portion. Any help would be greatly appreciated.
import _ from 'lodash';
import React from 'react';
import {GridList, GridTile} from 'material-ui/GridList';
import Subheader from 'material-ui/Subheader';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
//GridList style
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
gridList: {
width: 1000,
height: 500,
},
};
//data for the GridList
var tilesData = [
{
img: './images/image_01.jpg',
title: 'Breakfast',
likes: 0,
},
{
img: './images/image_02.jpg',
title: 'Tasty burger',
likes: 0,
},
{
img: './images/image_03.jpg',
title: 'Camera',
likes: 0,
},
{
img: './images/image_04.jpg',
title: 'Morning',
likes: 0,
},
{
img: './images/image_05.jpg',
title: 'Hats',
likes: 0,
},
{
img: './images/image_06.jpg',
title: 'Honey',
likes: 0,
},
{
img: './images/image_07.jpg',
title: 'Vegetables',
likes: 0,
},
{
img: './images/image_08.jpg',
title: 'Water plant',
likes: 0,
},
];
export default class Grid extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
this.post = this.post.bind(this);
this.delete = this.delete.bind(this);
}
//if Like button is clicked
post(){
this.setState({ like: true});
let likes = this.state.likes;
likes++;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
//if Like button is "unclicked"
delete(){
this.setState({ like: false});
let likes = this.state.likes;
likes--;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render(){
const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
return (
<div style={styles.root}>
<GridList
cellHeight={200}
cols={4}
style={styles.gridList}
>
<Subheader>December</Subheader>
{tilesData.map((tile) => (
<GridTile
key={tile.img}
title={tile.title}
subtitle={<span>Likes: <b>{tile.likes}</b></span>}
actionIcon={likeBtn}
>
<img src={tile.img} />
</GridTile>
))}
</GridList>
</div>
);
}
}
Grid.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
}
Problem
'State' of like button is defined outside the loop means same 'state' is shared with all GridTile components(for all images).
When you clicked on 'like' button then you are changing the 'state' of 'like' button in parent component that is Grid and same 'state' is used for all like buttons.
That's why it is impacting all like buttons.
Solution
'state' should be defined separately for each like button. Also delete and post method should be defined inside loop means in GridTile.
But GridTile is part of material-ui library so instead of changing this library create a wrapper on GridTile component.
Grid component will call component lets say it GridTileCustom component inside loop.
Inside GridTileCustom component you need to define delete and post method which you are using in 'onClick' event
So your final code will look like
import React from 'react';
import {GridList, GridTile} from 'material-ui/GridList';
import Subheader from 'material-ui/Subheader';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import IconButton from 'material-ui/IconButton';
const thumbsIcon = "glyphicon glyphicon-thumbs-up";
const styles = {
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
},
gridList: {
width: 1000,
height: 500,
},
};
var tilesData = [
{
img: './images/image_01.jpg',
title: 'Breakfast',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_02.jpg',
title: 'Tasty burger',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_03.jpg',
title: 'Camera',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_04.jpg',
title: 'Morning',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_05.jpg',
title: 'Hats',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_06.jpg',
title: 'Honey',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_07.jpg',
title: 'Vegetables',
likes: 0,
icon: './images/icons/icon_1.png',
},
{
img: './images/image_08.jpg',
title: 'Water plant',
likes: 0,
icon: './images/icons/icon_1.png',
},
];
export default class Grid extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
// this.post = this.post.bind(this);
// this.delete = this.delete.bind(this);
}
// post(){
// this.setState({ like: true});
// let likes = this.state.likes;
// likes++;
// this.setState({likes: likes});
// //this.tilesData.likes = likes;
// }
// delete(){
// this.setState({ like: false});
// let likes = this.state.likes;
// likes--;
// this.setState({likes: likes});
// //this.tilesData.likes = likes;
// }
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
render(){
return (
<div style={styles.root}>
<GridList
cellHeight={200}
cols={4}
style={styles.gridList}
>
<Subheader>December</Subheader>
{tilesData.map((tile) => (
<GridTileInternal
key={tile.img}
img={tile.img}
title={tile.title}
subtitle={tile.likes}
// actionIcon={likeBtn}
>
</GridTileInternal>
))}
</GridList>
</div>
);
}
}
class GridTileInternal extends React.Component {
constructor(props){
super(props);
this.state = {
like: false,
likes: tilesData.likes,
};
this.post = this.post.bind(this);
this.delete = this.delete.bind(this);
}
post(){
this.setState({ like: true});
let likes = this.state.likes;
likes++;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
delete(){
this.setState({ like: false});
let likes = this.state.likes;
likes--;
this.setState({likes: likes});
//this.tilesData.likes = likes;
}
render(){
const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
return (
<GridTile
key={this.props.img}
title={this.props.title}
subtitle={<span>Likes: <b>{this.props.subtitle}</b></span>}
actionIcon={likeBtn}
>
<img src={this.props.img} />
</GridTile>
);
}
}
Grid.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
}

Resources