I am trying to move from using Mapbox.js with Leaflet to Mapbox GL.
I have the following geojson that should be rendered as per the image attached. Unfortunately, after reading many articles and through the documentation related to data driven visualisation I've hit a wall. Wondered if anyone could help with an example?!
Here's the geojson:
{ "type":"Feature",geometry: { "type":"Point","coordinates":[1.1147,51.7829] },properties: { "title":"Paul","marker-color":"#0094F7","marker-size":"large","marker-symbol":"star" } },
{ "type":"Feature",geometry: { "type":"Point","coordinates":[-2.34851,52.6123] },properties: { "title":"Will","marker-color":"#F9883E","marker-size":"large","marker-symbol":"1" } },
{ "type":"Feature",geometry: { "type":"Point","coordinates":[-2.76389,53.0232] },properties: { "title":"Mark","marker-color":"#F1574E","marker-size":"large","marker-symbol":"13" } },
{ "type":"Feature",geometry: { "type":"Point","coordinates":[-.127211,51.6014] },properties: { "title":"David","marker-color":"#83C736","marker-size":"large","marker-symbol":"20" } },
{ "type":"Feature",geometry: { "type":"Point","coordinates":[-2.06682,53.4986] },properties: { "title":"Adam","marker-color":"#FC5C53","marker-size":"large","marker-symbol":"rocket" } }
The colour values are set by the end user and could be anything so I can't just create a lot of images to suit, and the numbers refer to dates so will be 1-31.
Here's what it currently looks like in Mapbox.js:
Thanks all!
Using Markers, you have full control to display any HTML element you like - so you could use CSS to construct a circle or teardrop of the right color, or an SVG icon.
See this example: https://www.mapbox.com/mapbox-gl-js/example/custom-marker-icons/
Essentially, instead of adding the GeoJSON directly as a source into the map, you will want to iterate over each point, and add markers onto the map.
Related
I am working on a project that utilizes Leaflet with a lot of tailored markers and colored lines/polygons. We are not using a GeoJSON layer in Leaflet.
I would like to export all or a subset of these objects/layers to GeoJSON and then import them back in without losing any detail like color and description.
Using the native toGeoJSON function of Leaflet, I can get GeoJSON data for anything I want on the map. Here is some code that produces GeoJSON for everything on the map:
function exportToGeoJSON() {
var allMarkersObjArray = [];
map.eachLayer(function (layer) {
allMarkersObjArray.push(layer);
});
var layerGroup = L.layerGroup(allMarkersObjArray);
var data = layerGroup.toGeoJSON();
var json = JSON.stringify(data); // Stringify the object
return json;
}
A snippet of the resulting GeoJSON created looks like this:
{
"type":"Feature",
"properties":{},
"geometry":{
"type":"Point",
"coordinates":[-75.668159,36.014897]}
}
We get the basic geometry which is nice but no properties with things like:
"properties": {
"id": 1,
"name": “Marker 1”,
"description": “This is a marker”,
"marker-size": "small",
"marker-color": "#f5a91a",
"marker-symbol": "b"
}
I want to find the best way to create these properties. I could certainly build the code to extract the properties from the Leaflet Marker object as an example but maybe there is a better way.
I have searched for potential plug-ins to do this but nothing is coming up on the radar screen. I would think other folks would like this type of capability.
Anyway, any thought or comments are welcome.
I am rendering a Gantt chart with different series color. The colors are somehow not reflected on the navigator at the bottom. How can I display the same colors in both series and navigator?
Fiddle link : Fiddle
Note: These colors are going to be dynamic which will be based on different cases. So I want them to reflect in the navigator too, dynamically.
I am changing color of the series like so :
chart: {
events: {
load: function() {
Highcharts.each(this.series[0].points, function(p) {
p.color = 'grey'
});
}
}
},
As you can see series color is grey but in the navigator below, I see different colors.
As per highcharts-gantt documentation:
Update the series with a new set of options. For a clean and precise handling of new options, all methods and elements from the series are removed, and it is initialized from scratch.
On event, you should then go through given serie points and change its options (in your case 'color').
The changes will be applied in the timeline below - example code changes the color after 1,5sec.
//Updating the color
setTimeout(function() {
for (var i = 0; i < chart.series[0].points.length; i++) {
chart.series[0].points[i].update({
color: "grey"
});
}
}, 1500);
Working example
In your code it would be:
events: {
load: function() {
Highcharts.each(this.series[0].points, function(p) {
p.update({color: "grey"});
});
}
}
To avoid shrink of timeline - launch setExtremes() after chart update.
Fires when the minimum and maximum is set for the axis, either by calling the .setExtremes() method or by selecting an area in the chart.
//Fully selected timeline
this.xAxis[0].setExtremes();
Working example - timeline selection
You can also set options for series of navigator, like below:
navigator: {
series: {
...,
colorByPoint: false,
color: 'grey'
},
...
}
Live demo: https://jsfiddle.net/BlackLabel/c4j9dvqx/
API Reference: https://api.highcharts.com/gantt/navigator.series.color
I'm using Vizframe component where there is two lines, when I try to show the Datalabel, the modifications is applied to both lines, I want to apply it just to one of them (A line with Datalabel set to True and a line with DataLabel set to False.)
Here's how it looks
This is how I change DataLabel property:
plotArea: {
dataLabel: {
visible: false
},
},
Well I know that this question might be older, but I had a similar issue recently. You can use the renderer function to customize the data labels to your needs.
For me, it worked, when I checked the context data for the correct measure and decide then, if I return nothing, which shows the label normally or return an empty DOM node.
dataLabel: {
visible: true,
style: {
color: "#000"
},
renderer: function (ctx) {
var node = document.createElement("text");
if (ctx.ctx.measureNames === "Optimum") {
var text = document.createTextNode("");
node.appendChild(text);
return node;
}
}
},
As you can see in the picture below, the label for the orange line (Optimum) is gone.
You can hide the values when they are overlapped using this:
plotArea: {
dataLabel: {
visible: true,
hideWhenOverlap: true
}
}
Julian's answer is useful yet in order for the change to take effect on the document we need to attach the returned node to the parent data point node.
The renderer function does not provide data regarding the graph itself but only the selected label, which leaves us clueless on how to render the node effectively.
Something like this would make me happier:
renderer: function(...) {
var parent = document.getElementById(some_given_data_point_id);
parent.appendChild(text_node);
return parent;
}
I would like to ask how can I position bottom labels using ChartJS library to display them like on the image below:
I tried to find it in official docs, but without the luck.
Many thanks for any advice.
In the xAxe ticks attribute, you can edit the userCallback property to change what is displayed on your labels. Furthermore, if you return an array of strings, every string will be displayed with line breaks.
So if you combine these two informations, you'll get the following :
options: {
scales: {
xAxes: [{
ticks: {
userCallback: function(tick, value, ticks) {
// `ticks` is the default display
// `.split("")` makes it an array of every character
return tick.split("");
}
}
}]
}
}
You can see a working example on this jsFiddle and here is its result :
I have been working on this for a number of days now, but my limited JS knowledge seems to hurt me.
I am creating a dynamic Ext.Carousel component in my ST2 application, which is based on the contents of a Store file.
That all works fine, but I will show the code anyway, so that nothing is left to imagination:
Ext.getStore('DeviceStore').load(
function(i) {
Ext.each(i, function(i) {
if (i._data.name == 'Audio Ring') {
var carousel = Ext.ComponentManager.get('speakerCarousel');
var items = [];
Ext.each(i.raw.speakers, function(speaker) {
items.push({
sci: Ext.create('SmartCore.view.SpeakerCarouselItem', {
speakerId: speaker.speakerid,
speakerName: speaker.speakername,
speakerEnabled: speaker.speakerenabled
})
});
});
carousel.setItems(items);
}
});
})
Now, this adds me the appropriate number of items to the carousel. They display, but without the content I specified:
This is the Carousel itself:
Ext.define('SmartCore.view.SpeakerCarousel', {
extend: 'Ext.Carousel',
xtype: 'speakerCarousel',
config: {
id: 'speakerCarousel',
layout: 'fit',
listeners: {
activeitemchange: function(carousel, item) {
console.log(item);
}
}
}
});
This is the item class, that I want to fill the data from the store into:
Ext.define("SmartCore.view.SpeakerCarouselItem", {
extend: Ext.Panel,
xtype: 'speakerCarouselItem',
config: {
title:'SpeakerCarouselItem',
styleHtmlContent: true,
layout: 'fit'
},
constructor : function(param) {
this.callParent(param);
this.add(
{
layout: 'panel',
style: 'background-color: #759E60;',
html: 'hello'
}
)
}
});
Again, the right number of items shows in the carousel (11), but the content is not visible, nor is the background colour changed.
When I check the console.log(item) in the browser, the items show as innerItems inside the carousel object.
Any help is greatly appreciated!!
Well, I fixed it myself, or better, I found a workaround that seems to be what I want.
I ended up ditching the constructor all together.
Instead I overwrote the apply method for the 'speakerName' key-value pair.
From there, I can use:
this._items.items[0]._items.items[i].setWhatever(...)
to set the content inside the item.
If anyone knows the "real" way to do this, I would still greatly appreciate input!