I want to make a panel. The longitude and latitude of the selected elements and the rotation angle are displayed on the panel. I use the panel to adjust the position and angle of the elements. However, with the editor, the modified elements can only be updated after applyedits is applied. I hope I can see the modification process in real time. This problem has been bothering me for a long time, so I hope someone can give me some advice.
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>
Thematic multivariate visualization (2D) | Sample | ArcGIS API for
JavaScript 4.22
</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#search {
display: block;
position: absolute;
z-index: 2;
top: 20px;
right: 20px;
}
#exit{
display: block;
position: absolute;
z-index: 2;
top: 50px;
right: 50px;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.22/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/Legend",
"esri/Graphic",
"esri/widgets/Editor"
], (Map, MapView, FeatureLayer, Legend, Graphic, Editor) => {
const map = new Map({
basemap: {
portalItem: {
id: "ba223f982a3c4a0ea8c9953346e2a201"
}
},
});
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 14,
center: [-88, 41]
});
view.ui.add(
new Legend({
view: view
}),
"bottom-right"
);
let axisPng = 'axle.png';
////////////////////////// 实时编辑功能/////////////////////////////////////////////
let AxisPoint = [
{
type: "point",
longitude: 121.08058594084916,
latitude: 37.69302040429612,
symbolType: "picture-marker",
id: 1,
url: axisPng,
width: "24px",
height: "24px",
name: "gz1",
angle: "0",
},
{
type: "point",
longitude: 121.08058594084919,
latitude: 37.692905793166474,
symbolType: "picture-marker",
id: 2,
url: axisPng,
width: "24px",
height: "24px",
name: "gz2",
angle: "90",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.6927572229193,
symbolType: "picture-marker",
id: 3,
url: axisPng,
width: "24px",
height: "24px",
name: "gz3",
angle: "60",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.69306479108028,
symbolType: "picture-marker",
id: 4,
url: axisPng,
width: "24px",
height: "24px",
name: "gz4",
angle: "0",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.693038260757845,
symbolType: "picture-marker",
id: 5,
url: axisPng,
width: "24px",
height: "24px",
name: "gz5",
angle: "0",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.693038260757845,
symbolType: "picture-marker",
id: 6,
url: axisPng,
width: "24px",
height: "24px",
name: "gz6",
angle: "0",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.69308397577108,
symbolType: "picture-marker",
id: 7,
url: axisPng,
width: "24px",
height: "24px",
name: "gz7",
angle: "0",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.693098832743665,
symbolType: "picture-marker",
id: 8,
url: axisPng,
width: "24px",
height: "24px",
name: "gz8",
angle: "0",
},
{
type: "point",
longitude: 121.08058057642913,
latitude: 37.693123463156034,
symbolType: "picture-marker",
id: 9,
url: axisPng,
width: "24px",
height: "24px",
name: "gz9",
angle: "0",
},
];
let temporaryAxis = [];
AxisPoint.forEach((item) => {
const AxisProperties = {
Name: item.name,
Angle: item.angle,
id: item.id,
opacity: item.opacity,
gisRack: item.gisRack,
Size: item.scaleX,// 使用scaleX来代表xy同时缩放的比例,单独缩放暂未找到方法
...item
};
const axisGraphic = new Graphic({
geometry: item,
attributes: AxisProperties,
spatialReference: { wkid: 3857 },
});
//存储管轴图形
temporaryAxis.push(axisGraphic);
})
AxleLayer = new FeatureLayer({
title: "管轴图层",
id: "AxisLayer",
//图层资源
source: temporaryAxis,
objectIdField: "id",
//渲染器
renderer: {
// 简单渲染
type: "simple",
// 设置渲染的统一样式
symbol: {
type: "picture-marker",
width: "36px",
height: "36px",
url: axisPng,
// angle: "0"
},
// 根据属性字段中的angle字段的值,单独改动渲染的角度信息,实现角度旋转
visualVariables: [
{
type: "rotation",
field: "angle",
rotationType: "geographic",
},
],
},
fields: [
{
name: "Name",
type: "string",
},
{
name: "Angle",
type: "string",
},
{
name: "id",
type: "integer",
},
{
name: "opacity",
type: "string",
},
{
name: "gisRack",
type: "integer",
},
{
name: "Size",
type: "string",
}
],
//弹出模板
popupTemplate: {
overwriteActions: true,
title: "管轴基础信息",
content: [
{
type: "fields",
fieldInfos: [
{
fieldName: "Name",
label: "管轴名称",
},
{
fieldName: "Angle",
label: "旋转角度",
},
],
},
],
// TODO 在此筛选各图层的图元
},
});
map.add(AxleLayer, 1);
editor = new Editor({
//编辑器所在视图,
view: view,
visible: false,// 关闭编辑面板显示
supportingWidgetDefaults: {// 编辑器默认参数设置--方法1
sketch: {
defaultUpdateOptions: {
enableRotation: false,// 禁用旋转
tool: "reshape",// 默认开启重塑工具
enableScaling: false,// 禁用缩放
toggleToolOnClick: false// 禁用点击切换编辑工具
}
}
}
});
view.on("click", (e) => {
// 点击左键才弹窗
if (e.button === 0) {
view.hitTest(e).then((pickerfeature) => {
// 开启编辑
editor.startUpdateWorkflowAtFeatureEdit(pickerfeature.results[0].graphic);
});
}
// 点击中键
if(e.button === 1){
changePosition(editor, AxleLayer)
}
if(e.button === 2){
exitEdit(editor, AxleLayer)
}
});
function changePosition(editor, AxleLayer){
let getUpdateFeatures = editor.viewModel.sketchViewModel.updateGraphics.items;
let newData = getUpdateFeatures;
newData[0].geometry.latitude += 0.0005;// 修改经纬度
newData[0].geometry.longitude += 0.0005;
newData[0].attributes.Angle += 20;// 修改角度
// console.log("接受到的编辑数据newData[0]", newData[0]);
let edits = {
updateFeatures: newData
};
AxleLayer.applyEdits(edits);
console.log();
};
function exitEdit(editor, AxleLayer){
let getUpdateFeatures = editor.viewModel.sketchViewModel.updateGraphics.items;
let newData = getUpdateFeatures;
let edits = {
updateFeatures: newData
};
AxleLayer.applyEdits(edits);
editor.cancelWorkflow();
}
});
</script>
</head>
<body>
<div id="viewDiv">
</div>
</body>
</html>
I have a weird issue. I am displaying data from a neo4j database onto the highcharts. I am able to retrieve the data, but when i try to put it onto the charts, some of it doesnt display. Here is my gauge code
CustomGauge.vue
<template>
<highcharts :options="chartOptions"></highcharts>
</template>
<script>
import { Chart } from "highcharts-vue";
export default {
name: "CustomGuage",
components: {
highcharts: Chart
},
props: ["data", "title", "range1", "range2", "min", "max"],
data() {
return {
chartOptions: {
chart: {
type: "gauge",
// plotBackgroundColor: null,
// plotBackgroundImage: null,
// plotBorderWidth: 0,
// plotShadow: false,
//marginBottom: 170,
},
credits: {
enabled: false
},
title: {
text: this.title,
align: "left"
},
pane: {
startAngle: -150,
endAngle: 150,
size: 200,
background: {
borderWidth: 0
}
},
// the value axis
yAxis: {
min: this.min,
max: this.max,
// tickPixelInterval: 30,
// tickWidth: 2,
// tickColor: "#666",
plotBands: [
{
from: 0,
to: this.range1,
color: "#55BF3B" // green
},
{
from: this.range1,
to: this.range2,
color: "#DDDF0D" // yellow
},
{
from: this.range2,
to: 1000,
color: "#DF5353" // red
}
]
},
series: [
{
data: this.data
// tooltip: {
// valueSuffix: " km/h"
// }
},
// // {
// // data: this.target,
// // dataLabels: {
// // enabled: true,
// // format: "Target: {y}%",
// // verticalAlign: "bottom",
// // borderWidth: 0
// // //useHTML: true,
// // },
// }
]
}
};
},
watch: {
data(newVal) {
this.chartOptions.series[0].data = newVal;
}
}
};
I define my chart like this
<CustomGuage :title="gaugeTitle1" :data="gaugeData1" :min="gauge1min" :max="gauge1max" :range1="gauge1Range1" :range2="gauge1Range2" />
I initialize it in data() like this -
gaugeTitle1: [],
gaugeData1: [],
gauge1Range1: [],
gauge1Range2: [],
gauge1min: [],
gauge1max: [],
Using the neo4j-vuejs connector, i retrieve the data like this -
const session19 = this.$neo4j.getSession();
// KPI 1
session19
.run(
"match (n:proj) where exists(n.min) return n.name as title,n.min as min,n.max as max,n.range1
as range1,n.range2 as range2,n.target AS target, n.current as data"
)
.then((res) => {
// KPI 1-------------------------
this.data1 = res.records[0].get("data");
var a = JSON.parse(this.data1);
this.gaugeData1.push(a);
console.log(a)
this.min1 = res.records[0].get("min");
var b = JSON.parse(this.min1);
this.gauge1min = b;
console.log(this.gauge1min)
this.max1 = res.records[0].get("max");
var c = JSON.parse(this.max1);
this.gauge1max = c;
console.log(this.gauge1max)
this.title1 = res.records[0].get("title");
this.gaugeTitle1.push(this.title1)
console.log(this.gaugeTitle1);
})
.then(() => {
session.close();
});
The retrieval of data works fine, i checked in the console.The weird part is if i comment/uncomment or change something in CustomGauge.vue, the charts displays perfectly, displays everything perfectly from the database.But once i refresh the page, it is gone. Could someone help me out. thanks for your help in advance
Probably a reactivity issue.
Instead of
this.chartOptions.series[0].data = newVal;
Try
this.$set(this.chartOptions.series[0], 'data', newVal)
i have a vue app that showing google map by using vue2-google-map.
but i have a problem with to implement maps.infowindow to my marker because there are lack of vuejs stuff reference source.
this is my code for marker template :
<GmapMap ref="mapRef"
:center="{lat: 3.974341, lng: 102.438057}"
:zoom="7"
class="gmap"
>
<GmapMarker
:key="index"
v-for="(location, index) in markers"
:position="location"
:draggable="true"
icon="https://img.icons8.com/color/48/000000/map-pin.png"
/>
</GmapMap>
this is the script:
export default {
data() {
return {
markers: [],
infowindow: [],
};
},
async setMarker() {
const { data } = await LocationRepository.getData(); //get data from api
this.tempLatLong = data;
this.$refs.mapRef.$mapPromise.then((map) => {
this.markers = [];
this.infowindow = [];
const bounds = new this.google.maps.LatLngBounds();
for (let i = 0; i < this.tempLatLong.length; i += 1) {
const lati = parseFloat(this.tempLatLong[i].latitude);
const long = parseFloat(this.tempLatLong[i].longitude);
const location = new this.google.maps.LatLng(lati, long);
bounds.extend(location);
const marker =
{
lat: lati, lng: long
}
this.markers.push(marker);
//this is where the problem occur.
const content = '<div id="content">'+'<p>test</p>' +'</div>'
this.infowindow.push(content)
}
map.fitBounds(bounds);
map.panTo({ lat: 3.974341, lng: 102.438057 });
});
},
i referring to google map documentation about the infowindows but don't have any idea how to implement it into this code. can someone teach me how to use this infowindow in vuejs map.
here i have a working example from one of my projects. the data for the lat an lng comes from veux store. so you have to modify these
<template>
<GmapMap
:center="getCenterPosition"
:zoom="getZoomLevel"
map-type-id="roadmap"
style="width: 100%; height: 600px"
>
<GmapMarker
v-for="(m, index) in loadedDealers"
:key="index"
:position="{ lat: m.lat, lng: m.lng }"
:clickable="true"
:draggable="false"
#click="openInfoWindowTemplate(index)"
:icon="{ url: require('./test.png') }"
/>
<gmap-info-window
:options="{
maxWidth: 300,
pixelOffset: { width: 0, height: -35 }
}"
:position="infoWindow.position"
:opened="infoWindow.open"
#closeclick="infoWindow.open=false">
<div v-html="infoWindow.template"></div>
</gmap-info-window>
</GmapMap>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
infoWindow: {
position: {lat: 0, lng: 0},
open: false,
template: ''
}
}
},
computed: {
...mapGetters([
'getDealers',
'getCenterPosition',
'getZoomLevel',
]),
loadedDealers() {
return this.getDealers
}
},
methods: {
openInfoWindowTemplate(index) {
const { lat, lng, name, street, zip, city } = this.loadedDealers[index]
this.infoWindow.position = { lat: lat, lng: lng }
this.infoWindow.template = `<b>${name}</b><br>${street}<br>${zip} ${city}<br>`
this.infoWindow.open = true
},
}
}
I want to make the {{total}} update when I click #addToChart button and it gets the game price from the vue array.
HTML:
<p> Total Price: {{ total }} USD</p>
<button #click="addToChart" :disabled="!game.inStock"
:class="{ disabledButton: !game.inStock }">
Add to Chart
</button>
Vue:
el: "#app",
data: {
title: "",
about: "",
games: [{
id: 0,
title: "",
inStock: true,
price: 59,
},
{
id: 1,
title: "",
inStock: true,
price: 40,
},
methods: {
addToChart: function () {
this.cart += 1;
return total;
}
You need to define your total property in your data first.
Then just pass the price as argument of your addToCart function.
new Vue({
el: "#app",
data: {
title: "",
about: "",
games: [
{ id: 0, title: "Game 1", inStock: true, price: 59 },
{ id: 1, title: "Game 2", inStock: true, price: 40 }
],
total: 0
},
methods: {
addToChart: function (price) {
this.total += price
}
}
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.min.js"></script>
<div id="app">
<p> Total Price: {{ total }} USD</p>
<div v-for="game in games">
{{ game.title }}
<button #click="addToChart(game.price)" :disabled="!game.inStock">Add to Chart</button>
</div>
</div>
For a location in a map, I would like to add a computed array in my object like this one:
marker: L.latLng(33.901445, -5.532788),
Actual Data:
Projects: [
project [0]:{
lat : 10.0
lng: -10.0
},
project [1]:{
lat : 15.0
lng: -15.0
},
],
The result i want :
Projects: [
project [0]:{
lat : 10.0
lng: -10.0
marker : L.latLng(10.0, -10.0)
},
project [1]:{
lat : 15.0
lng: -15.0
marker : L.latLng(15.0, -15.0)
},
],
Thank you
I found this code, thanks.
export default {
computed: {
NewObject() {
return this.projects.map(project => {
let p = project;
p.marker = [{
lat: project.lat,
lng: project.lng,
}];
return p;
});
},
}
}
In Template :
<div class="col-md-4" v-for="project in NewObject">
<l-map :zoom="zoom" :center="project.marker[0]" #click="">
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
<l-marker :lat-lng="project.marker[0]" #click=""></l-marker>
</l-map>
</div>
I think you want a simple method that can return an object for you. Are you using https://www.npmjs.com/package/vue2-google-maps
<template>
<div id="app">
<pre>{{projects}}</pre>
</div>
</template>
<script>
export default {
name: "App",
methods: {
setMarkerPosition(lat, lng) {
return { lat: lat, lng: lng };
},
addMarkerPosition(project) {
project.markerCenter = this.setMarkerPosition(project.lat, project.lng);
console.log(project);
}
},
mounted() {
this.projects.forEach(project => {
this.addMarkerPosition(project);
});
},
data() {
return {
projects: [
{
lat: 10.0,
lng: -10.0,
markerCenter: null
},
{
lat: 15.0,
lng: -15.0,
markerCenter: null
}
]
};
}
};
</script>
Edit: if you want markerCenter to be reactive i believe you need to include it on your data shape at the beginning, as a heads up.
Edit 2: There was a slight bug in my code i updated it.