How can I add the countries' names upon the geochoropleth map ? - dictionary

I'm working with dc.js and I'm about to create a world map.
How can I add the countries' names upon the geochoropleth map ?

I create a crude example of this approach here: http://jsfiddle.net/djmartin_umich/9VJHe/
1) First I attained the json file containing the centroids of all of the states: https://bitbucket.org/john2x/d3test/src/2ce4dd511244/d3/examples/data/us-state-centroids.json. For the purposes of this example, I copied the json to the jsfiddle.
var labels = {"type":"FeatureCollection","features":[
{"type":"Feature","id":"01","geometry":{"type":"Point","coordinates":[-86.766233,33.001471]},"properties":{"name":"Alabama","population":4447100}},
{"type":"Feature","id":"02","geometry":{"type":"Point","coordinates":[-148.716968,61.288254]},"properties":{"name":"Alaska","population":626932}},
2) Then I added a svg element to the chart that would contain all of the labels:
var labelG = d3.select("svg")
.append("svg:g")
.attr("id", "labelG")
.attr("class", "Title");
3) Next I added a svg text element for every state in the labels json:
labelG.selectAll("text")
.data(labels.features)
.enter().append("svg:text")
4) Then I positioned the text elements using the coordinates of the centroid. To accomplish this you should use the projection from the chart to translate the coordinates to relative x and y values.
.attr("x", function(d){return project(d.geometry.coordinates)[0];})
.attr("y", function(d){return project(d.geometry.coordinates)[1];})
.attr("dx", "-1em");
Here is the final result:
You'll notice two problems:
There isn't enough room to display all of the names in the northeast states
The labels aren't centered very well
Both of these problems could be resolved by changing the labels json by manually moving the coordinates.
Note, I used this question as a basis for my answer: https://groups.google.com/forum/#!topic/d3-js/uAWkwnuNQ3Q

Related

How can I keep map labels under a Polygon in Google Maps SDK for IOS?

Is there any way to keep the map labels with street names and POIs under GMSOverlays like GMSPolygons and GMSPolylines?
I have tried with different Zindex but to no vail.
This is what I get:
But as the polygon is the important thing here, I don't want the map labels on top of it, because they are, in my case, irrelevant. Besides I use a semitransparent fill color and you can still see the street names through it.
Answering my own question:
The only way I found was to add a Tile layer on top of the mapView like this:
mapView.mapType = .none // Set the map type to .none, as it will not be visible
let urls: GMSTileURLConstructor = { (x, y, zoom) in
let url = "https://mt1.google.com/vt/lyrs=r&x=\(x)&y=\(y)&z=\(zoom)&scale=2"
return URL(string: url)
}
let layer = GMSURLTileLayer(urlConstructor: urls)
layer.tileSize = 1024 // To get bigger fonts in mobile device with high resollution
layer.map = mapView
The only drawback is that when the map is rotated the labels are rotated too as you can see in this screenshot:

D3.js: Why are my legend tick marks' text disappearing?

I have a linear-gradient legend for my map. The x-axis values are calculated based on the minimum
and maximum values from the underlying data. I adapted this legend from this website:
https://www.visualcinnamon.com/2016/05/smooth-color-legend-d3-svg-gradient.html
The legend shows up when user selects a "field condition" from the dropdownlist. However, when
user selects a "state" from a dropdownlist, all the tick marks' text disappear. Same thing when user
selects a "county" from another dropdownlist. I haven't had luck trying to figure this out.
I'm calculating the tick mark values (shows as text) as follows:
var dataRange = getDataRange();
var min = parseFloat(dataRange[0].toFixed(3));
var max = parseFloat(dataRange[1].toFixed(3));
var legendW = 160, legendH = 20;
//create tick marks
var legendX = d3.scaleLinear()
.domain([min, max])
.range([0, legendW]);
var axis = d3.axisBottom(legendX);
d3.select("#svgLegend")
.attr("class", "axis")
.attr("width", legendW)
.attr("height", legendH * 2)
.append("g")
.attr("id", "g-legend")
.attr("transform", "translate(2," + legendH + ")") //margin.left; height/2
.call(axis);
For working example, please see: http://realtimeceap.brc.tamus.edu
I just glanced at the code on the page you referenced the working example at and think I figured out the issue.
Here's the line that taking out the ticks from the legend SVG:
d3.selectAll("text").remove();
which is a part of the onChange function for $("#stateSelect").
Line number: 279 to be more specific (in index.html file)
I think you want to take out all the texts from the mainSVG i.e. with the id: svgMap2.
Changing the above selection will fix the issue. (for eg. if you have a class for the texts to be removed, use d3.selectAll('text.<classname>').
Hope this helps.
I figured out why it's "disappearing". The Web is a stateless medium. So, every time I changed selection from the dropdownlist, the svg refreshes and losses its current state. So I needed to re-create my legend for the state and county dropdownlists. But also, for the county dropdownlist, since there is a Zoom function, it meant that everytime I zoom to another county, I loss my map state again. So I moved the recreate legend function into the zoomedIn method (that is, AFTER the zoom state). It works now.

How do you predict obj positions before placing it on the plane?

I am having trouble to set obj position before placing it in the scene.
is there a logical map or structure you follow to lay the objects without constant refreshing while adjusting x,y,z coordinates?
Maybe you can use the a-animation to do that! Or you can
use the entity.addEventListener to update the position.
Do you want layout? https://github.com/ngokevin/aframe-layout-component
Or do you want to:
var sceneEl = document.querySelector('a-scene');
var el = document.createElement('a-entity');
el.setAttribute('position', '1 2 3');
sceneEl.appendChild(el);

predicted rendering of css 3d-transformed pixel

I'm working in html, css, and javascript with canvas elements. Sometimes these canvases get css3 3d transformations applied to them (including zooms, rotations, and translations), and I need to predict the 2d-rendered-in-the-browser position of my 3d-transformed canvas, and I'm having some issues with it.
The transformations are actually not being applied to the canvas itself; they're being applied to two container divs around the canvas:
<div class="viewport">
<div class="container-outer">
<div class="container-inner">
<canvas></canvas>
</div>
</div>
</div>
The reason I have two containers is so I can apply two transformations at once. I have css transitions activated on the transforms, so I can, for example, do an x-translation on one container and a y-translation on the other container, and if they have separate easing functions, the resulting animation is a curve rather than a straight line of motion.
I am attempting to predict the position of the four corners of container-inner. The methods I'm using are correctly predicting the result of translations and zooms, but not rotations. Here's how it works. I start with the known original position of a corner, say [0,0,0]. For the sake of the example, we'll say that all of my divs and my canvas are all 500px x 500px, and I have a perspective of 500px set on the viewport div. So my perspective origin is at [250,250,500]. So I take my known corner position, convert it to a heterogeneous 4x1 vector matrix [0,0,0,1], and use matrixVectorMultiply() to multiply that by the matrix3d css matrix corresponding to the transformation being applied to container-inner. I take the resulting vector and use matrixVectorMultiply() again to multiply it by the matrix3d css matrix corresponding to the transformation being applied to container-outer.
matrixVectorMultiply = function(mx, vec)
{ // Given a 4x4 transformation matrix and an xyz vector, this will return the dot product (a new vector)
if (typeof vec.z == 'undefined')
{
vec.z = 0;
}
return {
x: vec.x*mx.array[0] + vec.y*mx.array[1] + vec.z*mx.array[2] + mx.array[3]
,y: vec.x*mx.array[4] + vec.y*mx.array[5] + vec.z*mx.array[6] + mx.array[7]
,z: vec.x*mx.array[8] + vec.y*mx.array[9] + vec.z*mx.array[10] + mx.array[11]
};
};
'vec' is a simple object with x, y, and z attributes. 'mx' is a simple object with two attributes, 'array' containing a row-primary array representation of the matrix3d transformation array, and 'string' containing a column-primary string representation of that array, ready to be plugged into a CSS transform attribute.
Now I have a 3d coordinate that should be the new position of my corner, after the outer and inner transitions have both been performed. But I need to project that 3d coordinate into my 2d viewing window, with the following function:
projection3d = function(pos, origin)
{ // Given an xyz point and an xyz perspective origin point, this will return the xy projected location
// Using the equation found here: http://en.wikipedia.org/wiki/3D_projection#Diagram
var pos2d = {x: null, y: null, z: null},
relPos2d = {x: null, y: null},
relPos = {x: null, y: null, z: null};
// First, we take our given point and locate it relative to the perspective origin, rather than the screen
relPos.x = pos.x - origin.x;
relPos.y = pos.y - origin.y;
relPos.z = pos.z - origin.z;
// Then we take this object and project it onto our 2d plane
relPos2d.x = relPos.x * (Math.abs(origin.z) / Math.abs(relPos.z));
relPos2d.y = relPos.y * (Math.abs(origin.z) / Math.abs(relPos.z));
// Then we take this and locate it relative to the screen again, instead of the perspective origin
pos2d.x = relPos2d.x + origin.x;
pos2d.y = relPos2d.y + origin.y;
return pos2d;
};
I take the result of that function and visually compare it with the actual result of the css 3d transformations in the browser, and find that translations and zooms are being predicted correctly, but not rotations, and I can't for the life of me figure out why not.
Does anyone have any insight? Is there further information I should provide?

Style Point vector as Marker in Openlayers?

It seems like getting onDrag for Markers on OpenLayers isn't possible (this and this, as examples)
So I would like to use a vector layer, and then add points to it instead of markers.
My problem is that the vector points doesn't look like the markers.
Can I assign an icon to a point feature?
I want the functionality of a vector point, with the look of a marker.
Add style object with externalGraphic property to your vector layer config:
var layer= new OpenLayers.Layer.Vector("example", {
maxExtent: new OpenLayers.Bounds(-200,-200,200,200),
style: {
externalGraphic: 'http://www.openlayers.org/dev/img/marker.png',
graphicWidth: 21,
graphicHeight: 25,
graphicYOffset: -24
}
});
The graphicYOffset shifts the marker appropriately so that the perceived tip of it corresponds to the location on the map.

Resources