I'm using amMap country map and want to show all country names in balloons without rollover or hover on that country. Means all balloons are visible on map load.
Showing more than one rollover balloon, or making it appear without hovering on a country is not possible, I'm afraid.
What you can do is to display a "label" on each of those countries. A label is an instance of MapImage with a text label and no actual image.
Placing an image/label for each country using longitude/latitude coordinate can be quite tedious work. Therefore you can use the following example which places area title in the geometrical center of each area automatically.
http://codepen.io/amcharts/pen/5687a78507081e1c8779cf067b762de7
The above map is for the United States, but you can use the code in it to process labels on just about any map.
The following code is responsible for that:
map.addListener("init", function () {
// set up a longitude exceptions for certain areas
var longitude = {
"US-CA": -130,
"US-FL": 120,
"US-TX": 1,
"US-LA": 40
};
var latitude = {
"US-AK": -85
};
setTimeout(function () {
// iterate through areas and put a label over center of each
map.dataProvider.images = [];
for( x in map.dataProvider.areas ) {
var area = map.dataProvider.areas[ x ];
area.groupId = area.id;
var image = new AmCharts.MapImage();
image.latitude = latitude[ area.id ] || map.getAreaCenterLatitude( area );
image.longitude = longitude[ area.id ] || map.getAreaCenterLongitude( area );
image.label = area.id.split('-').pop();
image.title = area.title;
image.linkToObject = area;
image.groupId = area.id;
map.dataProvider.images.push( image );
}
map.validateData();
console.log(map.dataProvider);
}, 100)
});
Please note, that sometimes country/state shapes will not make the dead center a perfect logical place to place a label. For those situations use the longitude and latitude overrides to adjust position of the label for the particular country.
Related
I am wondering if it is possible to get access to aggregated data from a deck.gl layer to be able to draw a legend.
Because the colour scheme is supplied I would only require the extent of the aggregated values calculated by the screengrid layer to be able to add this to the legend.
I know there are tooltips, but in some circumstances it would be nice to have access to these values.
I'm using the HexagonLayer and for that one you can find the values for the layers by using a semi custom onSetColorDomain function when initializing your layer. Then save the domain range array to a variable and call a make legend function.
for example:
const hexlayer = new HexagonLayer({
id: 'heatmap',
pickable: true,
colorRange: COLOR_RANGE,
data: feats_obj.coords_array,
elevationScale: 9,
extruded: true,
radius: 300,
getColorValue: points => {
if( points.length > max_points) {
max_points = points.length
}
renderCategories( incident_categories )
return points.length
},
onSetColorDomain: (ecol) => {
console.log('color domain set', ecol)
max_span.innerHTML = ecol[1]
color_domain = ecol;
create_legend()
// console.log('max_points: ', max_points)
},...
})
The hacky way i figured out was to make a max points in a polygon global variable outside initializing the layer and have it update the value anytime there's a polygon with more points in it than that max value. An example of it in the wild is: https://mpmckenna8.github.io/sfviz/?start_date=2020-05-01&end_date=2020-05-31 with a link to the repo u can hack on there.
I am working with a dataset where I am given time spent in locations or forms of transportation - I am trying to attach the marker clusters for forms of transportation on a line below each other on the right side of the map, such that one can see how much time is spent on each kind of transport.
I tried doing this by finding the latlong of the different pixel positions, each time the map moves, like so:
var centerPoint = map.getSize().divideBy(2);
map.on('move', function(e) {
var name_array = [];
var multiplier_x = 0.95;
var multiplier_y = 0.8;
var index = 0;
layer_group.eachLayer(function (layer) {
if (layer.feature.properties.Name == 'Cycling' || layer.feature.properties.Name == 'Walking' || layer.feature.properties.Name == 'Driving' || layer.feature.properties.Name == 'Boating' || layer.feature.properties.Name == 'On a bus' || layer.feature.properties.Name == 'On a train'){
if(!(layer.feature.properties.Name in name_array)){
var targetPoint = centerPoint.add([centerPoint.x*multiplier_x, -centerPoint.y*(multiplier_y-index)]),
targetLatLng = map.containerPointToLatLng(targetPoint);
name_array[layer.feature.properties.Name] = targetLatLng;
index += 0.2;
}
layer.setLatLng(name_array[layer.feature.properties.Name]);
}
});
});
The problem is that eventhough each transportation form is given a different location, they seem to cluster together anyway, and change between different clusters when the map is moved. Additionally, when moving the brush the map seems to move further and further to the left, as I am trying to fit the map to the bounds.
I don't know if it is possible to achieve what I am trying to - or if there maybe is another way of doing it, maybe by creating a seperate cluster group for the transportation, which I guess at least would make sure that the transportation isn't clustered with the locations?
Code: http://bl.ocks.org/skov94/e44fcebd282fe5eb4c708e8ba0af95d6
To plot them at a given pixel, based on a given latlng:
...
var topLeft = map._getNewPixelOrigin(map.getCenter(), map.getZoom());
var targetPoint = map.project(map.getCenter(), map.getZoom()).subtract(topLeft);
var targetLatLng = map.unproject(targetPoint);
...
By constantly calculating the new pixel origin, this ensures that the pixels and latLngs stay aligned even when panning
I have an gameobject1(added Scroll Rect component)and inside of it another gameobject2(The Scroll rect component's content).In gameobject2 has images.The number of images can be 10 or 20..(Any numbers).The Movement Type is Elastic.As you know it will stop scrolling only until gameobject2 height's length. How to stop on dynamic number's of length.In gameobject2 the number of images can be different. It depends on search results. The results can be 5,8, or 200. So I need to scroll until last of search result.So how to stop scrolling on exactly length in Scroll rect component?
You can use ContentSizeFitter component. GameObject with name "Content", is a content for scrollRect component of "ScrollView"-gameObject.
RectTransform#SetSizeWithCurrentAnchors
I use this a lot when building dynamic scrolling lists. After adding all the items I want (and each having a known size, and all positioned using that size) I update the content's RectTransform with the new size (total number of objects added * size of the object).
For example, I have this code:
int i = 0;
//for each item in a list of skills...
IEnumerator<Skill> list = SkillList.getSkillList();
Transform skillListParent = GuiManager.instance.skillPanel.transform;
while(list.MoveNext()) {
Skill sk = list.Current;
//create a prefab clone...
GameObject go = Main.Instantiate(PrefabManager.instance.SKILL_LISTITEM, skillListParent) as GameObject;
//set its position...
go.transform.localPosition = new Vector3(5, i * -110 -5, 5);
//add a button event or other data (some lines omitted)...
Transform t1 = go.transform.FindChild("BuyOne");
t1.GetComponent<Button>().onClick.AddListener(delegate {
doBuySkill(sk);
});
t1.GetChild(0).GetComponent<Text>().text = Main.AsCurrency(sk.getCost(1)) + " pts";
//track how many...
i++;
}
//update rect transform
((RectTransform)skillListParent).SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, (i * 110 + 10));
I have a sphere model along with html text labels overlayed onto it at fixed positions. How can I hide them when they are behind the object when i am rotating my sphere using orbit controls?
Anyone knows about any references on stackoverflow or any examples which can solve my issue?
See this example how you could do it: http://jsfiddle.net/L0rdzbej/194/
I have put the relevant code in the updateLabelVisibility()-function, it looks like this:
var meshPosition = mesh.getWorldPosition();
var eye = camera.position.clone().sub( meshPosition );
var dot = eye.clone().normalize().dot( meshPosition.normalize() );
//IS TRUE WHEN THE MESH IS OCCLUDED BY THE SPHERE = dot value below 0.0
var ocluded = dot < -0.2;
if ( ocluded ) {
// HIDE LABEL IF CAMERA CANT SEE IT (I.E. WHEN IT IS BEHIND THE GLOBE)
label.style.visibility = "hidden";
}
else {
// DISPLAY LABEL IF MESH IS VISIBLE TO THE CAMERA
label.style.visibility = "visible";
}
Where mesh is the marker where your label is attached to. The dot is basically telling you how far around the sphere it is, within a certain distance of 90 degree. Simply said by values below zero the label is longer visible by going further around the back.
To be fair I based this off some code from: https://zeitgeist-globe.appspot.com/
All nvd3 examples (which I've found) look like this:
return [
{
values: sin, //values - represents the array of {x,y} data points
key: 'Sine Wave', //key - the name of the series.
color: '#ff7f0e' //color - optional: choose your own line color.
}, ...]
I want to use a function which would use different keys based on the size of the chart / drawing area.
So if I have a large drawing area I have space for the whole name Sine Wave and in small areas I'd just display sin.
Yes, I could go through the series and update the key property, but it would be easier to put all the necessary data into the object and choose on render time, which key should be used.
You can use chart.legend.key()
chart.legend.key(function(d){
// Return the key you want for series d here based on screen realestate
// FYI: The default would return d.key
});
So it could look something like this:
function setLegendKeys(d){
var width = document.body.clientWidth;
var abbreviations = {
'Sine Wave': 'sin',
'Cosine Wave': 'cos'
};
if (width < 500){
return abbreviations[d.key];
}
return d.key;
}
chart.legend.key(setLegendKeys)
See this Plunk for a live example:
http://plnkr.co/edit/lisKuZ5ivj25QhyjlQUW?p=preview