Mapbox-gl-draw duplicating points on drag when editing linestring from geojson - mapbox-gl-draw

When I select a point on the map and drag the point to move it, it duplicates the point and creates a new line between the two points surrounding the selected point, which ultimately results in a triangle instead of me being able to just modify the existing line.
triangle created by duplicated point
I hastily threw this jsfiddle together but it demonstrates the issue i'm having when modifying an existing line (line is in blue, zoom in, click on it, select a point and draw):
map.on('load', function () {
map.addSource('multiple-lines-source', {
'type': 'geojson',
'data': geojson,
});
map.addLayer({
'id': 'multiple-lines-layer',
'type': 'line',
'source': 'multiple-lines-source',
'layout': {
},
'paint': {
'line-color': 'black',
},
});
let draw = new MapboxDraw()
map.addControl(draw)
draw.add(geojson)
});
jsfiddle
Anyone know how to fix this behavior? I just want to be able to move points and reposition them without creating a new point. When I draw a line from scratch and modify a point on that line it works perfectly.

Related

Problem painting a map with Openlayers using Vue

I'm writing an application in Vue that will have a map in it. I want to add some points in that map. The code relevant to the map is,
<div>
<vl-map :load-tiles-while-animating="true" :load-tiles-while-interacting="true" data-projection="EPSG:4326" style="height: 400px">
<vl-view :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation"></vl-view>
<vl-layer-tile>
<vl-source-osm></vl-source-osm>
</vl-layer-tile>
<vl-layer-vector>
<vl-source-vector :features="points"></vl-source-vector>
</vl-layer-vector>
</vl-map>
</div>
Here points is part of data points: []
If I write the points directly in data everything works.
Like,
points: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [0.0, 0.0]
},
properties: {}
]
shows a point in [0, 0].
However, I need to use a method that will call several APIs to find out the points that I need to show. It's when I write the code to prepare the points to have the correct value when everything stops working. I'm writing this code in the mounted section.
async calculatePoints () {
this.points = // points as I want them to be
}
But this is not working (although some few times works). Any idea what is going on here or which is the best way to handle this?

Finding Animated Bar Chart Library Or Component

I am interested in making a bar chart that changes over time (ideally bars will move up and down smoothly to show data changes over time). I didn't expect it would be difficult but, maybe due to the way I am searching, I cannot find a pre-built component or library that does this. I have come across other animated graphs that show data changes over time (like https://developers.google.com/chart/interactive/docs/gallery/motionchart and http://www.highcharts.com/demo/dynamic-update) but nothing that does what I describe in a bar chart. It would also work if I could find a line chart or pie chart that smoothly changed over time but I would rather make a bar chart to do this if possible.
Does an application or component or library like this exist (and if so can you point me in the right direction)? If for some reason nothing like this is available, what is the closest thing to it available (what is the path that would require the least amount of effort to produce this chart)?
ZingChart should be able to do this for you, and it's super easy to use. The chart configuration is defined using a JSON object. Inside the plot object, the animation object can hold a number of different animation options, including effect, speed, delay, and sequence. More information on ZingChart's animation effects can be found here. The render method is called to tell ZingChart where to render the chart using a div's unique ID. For this example, I configured a function to be called every 3000 milliseconds, generating a random array of numbers between 0 and 100, using the setseriesvalues method to change the data at plotindex 0.
var oData = {
"type": "bar",
"scaleY": {
"values": "0:100:10"
},
"plot": {
"animation": {
"effect": "ANIMATION_SLIDE_BOTTOM"
}
},
"series": [{
"values": [69, 68, 54, 48, 70, 74, 98, 70, 72, 68, 49, 69]
}]
};
zingchart.render({
id: 'myChartDiv',
width: 600,
height: 400,
data: oData
});
setInterval(function() {
var aValues = [];
for (var n = 0; n < 12; n++) {
var num = Math.random() * (100 - 0) + 0;
aValues.push(num);
}
console.log(aValues);
zingchart.exec('myChartDiv', 'setseriesvalues', {
plotindex: 0,
values: aValues
});
}, 3000);
<script src="http://cdn.zingchart.com/zingchart.min.js"></script>
<div id="myChartDiv"></div>
Full disclaimer: I'm on the ZingChart team, but if there's anything else I can help you with, I'd be happy to help!

Cytoscape : multiple instances and no graph display

I want to display several instances of cytoscape in a single page, in a time sequence: first one set of nodes are displayed on the graph, the user must interact with it (create edges), then he moves to a second graph (#cy0 is :hidden and #cy1 is :visible).
For code optimisation sake I wish to use the same initialisation function to display different successive sets of nodes. My initialisation function works fine in the first instance, but the graph is not created (cy.initrender() == false) in the second session. A command is probably missing, I tested a couple, but I don't see what to do.
Here is my code:
//elements
$(function(){ // on dom ready
var elesJson = {
nodes: [
{ data: { id: 'S', faveShape: 'rectangle',} }
...
],
edges: [
{ data: { id: 'loan', source: 'B', target: 'U' } },
...
],
};
// instance index
var indexLevel=0;
// cy initialisation
$("#cy"+indexLevel).cytoscape({
style: cytoscape.stylesheet()...
elements: elesJson,
ready: function(){
window.cy = this;});
// jQuery command to move from one instance to the other.
$('#next').click(function(){
$("#cy"+indexLevel).css("visibility","hidden");
indexLevel++;
$("#cy"+indexLevel).css("visibility","visible");
cy.load(elesJson);
cy.ready();
console.log(cy.initrender());
});
I am able to generate my node.collection, it is not empty, but the canvas element is not created and/or displayed within the #cy div, and cy.initrender() returns "false".
Any solution to this?
As noted in the docs for init, you must call cy.resize() if you play around with the cy div's display or position: http://js.cytoscape.org/#core/initialisation
cy.resize() : http://js.cytoscape.org/#core/viewport-manipulation/cy.resize
Edit: You may want to use z-index instead to simplify things...

Horizontal scrolling list

I would like to have images displayed in a horizontal list.
This is what I've done so far :
var list = Ext.create('Ext.List',{
store: store,
itemTpl: new Ext.XTemplate('<img src="{icon}" />'),
inline:true,
scrollable: {
direction: 'horizontal',
directionLock: true
}
});
My store has 5 items, but the list only display two (because the screen is not large enough to display more than two images).
I tried to solve this problem by setting the width of my list to 1000px like so :
style:'width: 1000px',
All the items are now shown, but now, the problem is the list is not scrollable anymore. I can't go further than the width of the screen.
[UPDATE]
I've tried with a hbox panel but nothing is showing. Any idea why ?
var hbox = Ext.create('Ext.Panel',{
layout:'hbox',
style:'background-color:red;',
data: [
{name: 'Jamie', age: 100},
{name: 'Rob', age: 21},
{name: 'Tommy', age: 24},
{name: 'Jacky', age: 24},
{name: 'Ed', age: 26}
],
tpl: new Ext.XTemplate('{name}')
});
this.setItems([hbox]);
I just see a red background?
Did you try passing an object instead of just true for the 'inline' config:
var list = Ext.create('Ext.List',{
store: store,
itemTpl: new Ext.XTemplate('<img src="{icon}" />'),
inline: { wrap: false },
scrollable: {
direction: 'horizontal',
directionLock: true
}
});
In the docs, they mention this avoids your wrapping problem and enables horizontal scrolling:
http://docs.sencha.com/touch/2-0/#!/api/Ext.dataview.DataView-cfg-inline.
I did not try it though.
Hope this will work for you.
Ok, I finally found this working example which was quite helpful :
http://dev.sencha.com/deploy/touch/examples/production/list-horizontal/index.html
You can also find it in the examples/production/list-horizontal when you download Sencha Touch 2
It's not a really good idea (or might be impossible) to create a horizontal Ext.List
If you tends to produce something like "image slider" or "carousel", then it would be better if you create an Ext.Carousel or something that is more customizable, hbox. Ext.Carousel is easy and well-documented, so I will talk a little bit more about hbox.
The idea is, first you create an empty hbox with fixed height. Then, you can eventually add items to it. Each item is whatever you like, for example: Ext.Image in your case. Each of your hbox item is a component then you can easily customize it the way you want.
Hope this idea helps.

When will Sencha Touch Charts handle events on DrawComponent Sprites?

In the Sencha Touch Charts 2 beta distribution, the Drawing guide example code has an example of a Sprite listening for touch start. The code given fails to draw any sprites, because it fails to insert a canvas onto the DOM. However this can be fixed by replacing this:
//add the component to the panel
Ext.create('Ext.chart.Panel', {
fullscreen: true,
title: 'Yellow Circle',
items: drawComponent
});
with this:
//add the component to the panel
Ext.create('Ext.chart.Panel', {
fullscreen: true,
title: 'Yellow Circle',
chart: drawComponent
});
Now, I'd really like to get the event handling to work. The example code continues with:
// Add a circle sprite
var myCircle = drawComponent.surface.add({
type: 'circle',
x: 100,
y: 100,
radius: 100,
fill: '#cc5'
});
// Now do stuff with the sprite, like changing its properties:
myCircle.setAttributes({
fill: '#ccc'
}, true);
// Remember always to refresh the image
drawComponent.surface.renderFrame();
// or animate an attribute on the sprite
// no need to refresh the image when adding animations.
myCircle.fx.start({
fill: '#555'
});
// Add a touch listener to the sprite
myCircle.addListener('touchstart', function() {
alert('touchstarted!');
});
but that final alert never happens on touch. Any ideas?
drawComponent.addListener('touchstart'... works fine, but is of course not localised to the circle sprite.
--- after more investigation ---
I think the answer is simply that event handling on sprites his not implemented yet. e.g. in touch-charts/src/draw/engine/Canvas.js we have in the definition of Ext.draw.engine.Canvas,
getSpriteForEvent: function(e) {
return null; //TODO!!!
},
OK - time to change the question from 'how?' to 'when?':
'When will Sencha Touch support Sprite event handling?"