Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cto
g1
Commits
1a892a7d
Commit
1a892a7d
authored
Jun 21, 2018
by
S Anand
Browse files
ENH: mapviewer: add scheme: option
parent
36adaa41
Pipeline
#51902
passed with stage
in 3 minutes and 1 second
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
1a892a7d
...
@@ -1078,13 +1078,10 @@ You can apply styles based on any attribute or function.
...
@@ -1078,13 +1078,10 @@ You can apply styles based on any attribute or function.
url
:
'
cities.json
'
,
url
:
'
cities.json
'
,
latitude
:
'
lat
'
,
latitude
:
'
lat
'
,
longitude
:
'
long
'
,
longitude
:
'
long
'
,
options
:
{
title
:
'
column-name
'
// TODO: implement as popup
},
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
pollution
'
,
metric
:
'
pollution
'
,
rang
e
:
'
RdYlGn
'
schem
e
:
'
RdYlGn
'
}
}
}
}
}
}
...
@@ -1112,10 +1109,16 @@ attribute.
...
@@ -1112,10 +1109,16 @@ attribute.
dataKey
:
'
name
'
,
// Join this column from the URL (data)
dataKey
:
'
name
'
,
// Join this column from the URL (data)
mapKey
:
'
ST_NM
'
// with this property in the GeoJSON
mapKey
:
'
ST_NM
'
// with this property in the GeoJSON
},
},
options
:
{
style
:
{
fillColor
:
'
#a00
'
,
fillOpacity
:
1
}
},
attrs
:
{
attrs
:
{
fillColor
:
{
// Fill the regions
fillColor
:
{
// Fill the regions
metric
:
'
score
'
,
// with the "score" column state_score.json
metric
:
'
score
'
,
// with the "score" column
from
state_score.json
rang
e
:
'
RdYlGn
'
// using a RdYlGn gradient
schem
e
:
'
RdYlGn
'
// using a RdYlGn gradient
},
},
tooltip
:
function
(
prop
)
{
// On hover, show this HTML tooltip
tooltip
:
function
(
prop
)
{
// On hover, show this HTML tooltip
return
prop
.
ST_NM
+
'
:
'
+
prop
.
TOT_P
return
prop
.
ST_NM
+
'
:
'
+
prop
.
TOT_P
...
@@ -1206,7 +1209,7 @@ Drilldown feature example:
...
@@ -1206,7 +1209,7 @@ Drilldown feature example:
-
`url`
is url (String) to fetch data
-
`url`
is url (String) to fetch data
-
`mapKey`
is attribute name in geojson to match
-
`mapKey`
is attribute name in geojson to match
-
`dataKey`
is column name in input dataset that matches with geojson
`mapKey`
-
`dataKey`
is column name in input dataset that matches with geojson
`mapKey`
-
`attrs`
Data driven styles.
-
`attrs`
Data driven styles.
same as
`options`
. (
`attrs`
take priority over
`options`
)
-
For
`color`
,
`weight`
,
`opacity`
,
`fillColor`
,
`fillOpacity`
properties, the options are:.
-
For
`color`
,
`weight`
,
`opacity`
,
`fillColor`
,
`fillOpacity`
properties, the options are:.
-
`metric`
string / function
-
`metric`
string / function
-
If
`metric`
: is a string, can be any numeric property of geojson
-
If
`metric`
: is a string, can be any numeric property of geojson
...
...
src/mapviewer.js
View file @
1a892a7d
...
@@ -136,6 +136,7 @@ MapViewer.prototype.mergeData = function (mapJSON, dataTable, mapKey, dataKey) {
...
@@ -136,6 +136,7 @@ MapViewer.prototype.mergeData = function (mapJSON, dataTable, mapKey, dataKey) {
feature
.
properties
[
key
]
=
row
[
key
]
feature
.
properties
[
key
]
=
row
[
key
]
}
}
})
})
// returning mapJSON to write unit testcases for mergeData
return
mapJSON
return
mapJSON
break
break
default
:
default
:
...
@@ -173,17 +174,21 @@ MapViewer.prototype.buildLayer = function (layerName, layerConfig) {
...
@@ -173,17 +174,21 @@ MapViewer.prototype.buildLayer = function (layerName, layerConfig) {
case
'
topojson
'
:
case
'
topojson
'
:
case
'
geojson
'
:
case
'
geojson
'
:
self
.
cacheData
(
layerName
,
layerConfig
[
dataOrURL
(
layerConfig
)]).
then
(
function
(
mapJSON
)
{
self
.
cacheData
(
layerName
,
layerConfig
[
dataOrURL
(
layerConfig
)]).
then
(
function
(
mapJSON
)
{
gLayer
=
new
L
.
TopoJSON
(
mapJSON
,
layerConfig
.
options
)
self
.
fitToLayer
(
gLayer
)
self
.
_saveLayer
(
layerName
,
gLayer
)
if
(
'
link
'
in
layerConfig
)
{
if
(
'
link
'
in
layerConfig
)
{
self
.
cacheData
(
layerName
,
layerConfig
.
link
[
dataOrURL
(
layerConfig
.
link
)]).
then
(
function
(
tableData
)
{
self
.
cacheData
(
layerName
,
layerConfig
.
link
[
dataOrURL
(
layerConfig
.
link
)]).
then
(
function
(
tableData
)
{
self
.
mergeData
(
mapJSON
,
tableData
,
layerConfig
.
link
.
mapKey
,
layerConfig
.
link
.
dataKey
)
self
.
mergeData
(
mapJSON
,
tableData
,
layerConfig
.
link
.
mapKey
,
layerConfig
.
link
.
dataKey
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
,
layerConfig
)
gLayer
=
new
L
.
TopoJSON
(
mapJSON
,
layerConfig
.
options
)
self
.
fire
(
layerName
+
'
loaded
'
)
self
.
_saveLayer
(
layerName
,
gLayer
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
)
self
.
fitToLayer
(
layerName
)
self
.
fire
(
layerName
+
'
loaded
'
)
})
})
}
else
{
}
else
{
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
,
layerConfig
)
gLayer
=
new
L
.
TopoJSON
(
mapJSON
,
layerConfig
.
options
)
self
.
_saveLayer
(
layerName
,
gLayer
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
)
self
.
fitToLayer
(
layerName
)
self
.
fire
(
layerName
+
'
loaded
'
)
self
.
fire
(
layerName
+
'
loaded
'
)
}
}
})
})
...
@@ -208,23 +213,27 @@ MapViewer.prototype.buildLayer = function (layerName, layerConfig) {
...
@@ -208,23 +213,27 @@ MapViewer.prototype.buildLayer = function (layerName, layerConfig) {
var
markerProxy
=
layerConfig
.
type
.
toLowerCase
()
===
'
circle
'
?
L
.
circle
:
L
.
circleMarker
var
markerProxy
=
layerConfig
.
type
.
toLowerCase
()
===
'
circle
'
?
L
.
circle
:
L
.
circleMarker
self
.
cacheData
(
layerName
,
layerConfig
[
dataOrURL
(
layerConfig
)]).
then
(
function
(
pointjson
)
{
self
.
cacheData
(
layerName
,
layerConfig
[
dataOrURL
(
layerConfig
)]).
then
(
function
(
pointjson
)
{
var
pointLayers
=
[]
var
pointLayers
=
[]
pointjson
.
forEach
(
function
(
d
)
{
function
create_layer
()
{
var
mark
=
markerProxy
([
d
[
layerConfig
.
latitude
],
d
[
layerConfig
.
longitude
]],
layerConfig
.
options
)
pointjson
.
forEach
(
function
(
d
)
{
mark
.
feature
=
{}
var
mark
=
markerProxy
([
d
[
layerConfig
.
latitude
],
d
[
layerConfig
.
longitude
]],
layerConfig
.
options
)
mark
.
feature
.
properties
=
d
mark
.
feature
=
{}
pointLayers
.
push
(
mark
)
mark
.
feature
.
properties
=
d
})
pointLayers
.
push
(
mark
)
self
.
fitToLayer
(
L
.
featureGroup
(
pointLayers
))
})
self
.
_saveLayer
(
layerName
,
L
.
featureGroup
(
pointLayers
))
self
.
_saveLayer
(
layerName
,
L
.
featureGroup
(
pointLayers
))
}
if
(
'
link
'
in
layerConfig
)
{
if
(
'
link
'
in
layerConfig
)
{
self
.
cacheData
(
layerName
,
layerConfig
.
link
[
dataOrURL
(
layerConfig
.
link
)]).
then
(
function
(
tableData
)
{
self
.
cacheData
(
layerName
,
layerConfig
.
link
[
dataOrURL
(
layerConfig
.
link
)]).
then
(
function
(
tableData
)
{
self
.
mergeData
(
pointjson
,
tableData
,
layerConfig
.
link
.
mapKey
,
layerConfig
.
link
.
dataKey
)
self
.
mergeData
(
pointjson
,
tableData
,
layerConfig
.
link
.
mapKey
,
layerConfig
.
link
.
dataKey
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
,
layerConfig
)
create_layer
()
self
.
fire
(
layerName
+
'
loaded
'
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
)
self
.
fitToLayer
(
layerName
)
})
})
}
else
{
}
else
{
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
,
layerConfig
)
create_layer
()
self
.
fire
(
layerName
+
'
loaded
'
)
if
(
'
attrs
'
in
layerConfig
)
self
.
_choropleth
(
layerName
)
self
.
fitToLayer
(
layerName
)
}
}
})
})
break
break
...
@@ -238,27 +247,36 @@ MapViewer.prototype._choropleth = function (layerName, layerConfig) {
...
@@ -238,27 +247,36 @@ MapViewer.prototype._choropleth = function (layerName, layerConfig) {
layer
.
eachLayer
(
function
(
sublayer
)
{
layer
.
eachLayer
(
function
(
sublayer
)
{
var
style
=
{},
prop
,
metricFormula
,
metric
,
domain
var
style
=
{},
prop
,
metricFormula
,
metric
,
domain
for
(
prop
in
layerConfig
.
attrs
)
{
if
(
prop
.
toLowerCase
()
==
'
tooltip
'
)
continue
for
(
prop
in
self
.
options
.
layers
[
layerName
].
attrs
)
{
metric
=
layerConfig
.
attrs
[
prop
].
metric
if
(
prop
.
toLowerCase
()
==
'
tooltip
'
)
continue
if
(
typeof
(
self
.
options
.
layers
[
layerName
].
attrs
[
prop
])
!=
'
object
'
)
{
style
[
prop
]
=
self
.
options
.
layers
[
layerName
].
attrs
[
prop
]
continue
}
metric
=
self
.
options
.
layers
[
layerName
].
attrs
[
prop
].
metric
if
(
typeof
(
metric
)
===
'
string
'
)
if
(
typeof
(
metric
)
===
'
string
'
)
metricFormula
=
(
row
)
=>
row
[
metric
]
metricFormula
=
(
row
)
=>
row
[
metric
]
else
else
metricFormula
=
metric
metricFormula
=
metric
if
(
layerConfig
.
attrs
[
prop
].
domain
)
if
(
self
.
options
.
layers
[
layerName
]
.
attrs
[
prop
].
domain
)
domain
=
layerConfig
.
attrs
[
prop
].
domain
domain
=
self
.
options
.
layers
[
layerName
]
.
attrs
[
prop
].
domain
else
else
domain
=
self
.
_calculateMinMax
(
layer
,
metricFormula
)
domain
=
self
.
_calculateMinMax
(
layer
,
metricFormula
)
// TODO: ENH: cache _calculateMinMax for each property bcz its same for each sublayer
if
(
prop
===
"
fillColor
"
||
prop
===
"
color
"
)
{
// skip scale if sublayer.feature.properties do not have that metric, shows as per settings in `options: {style: ...}`
if
(
metricFormula
(
sublayer
.
feature
.
properties
)
!==
undefined
)
style
[
prop
]
=
scale
([],
{
style
[
prop
]
=
scale
([],
{
metric
:
metric
,
metric
:
metric
,
domain
:
domain
,
domain
:
domain
,
scheme
:
layerConfig
.
attrs
[
prop
].
range
scheme
:
self
.
options
.
layers
[
layerName
].
attrs
[
prop
].
scheme
,
scale
:
self
.
options
.
layers
[
layerName
].
attrs
[
prop
].
scale
,
range
:
self
.
options
.
layers
[
layerName
].
attrs
[
prop
].
range
})(
sublayer
.
feature
.
properties
)
})(
sublayer
.
feature
.
properties
)
}
}
}
sublayer
.
setStyle
(
style
)
sublayer
.
setStyle
(
style
)
})
})
}
}
...
...
src/scale.js
View file @
1a892a7d
...
@@ -51,7 +51,6 @@ function scale (data, config) {
...
@@ -51,7 +51,6 @@ function scale (data, config) {
}
}
var
domain
=
config
.
domain
||
d3
.
extent
(
data
,
metricFormula
)
var
domain
=
config
.
domain
||
d3
.
extent
(
data
,
metricFormula
)
if
(
color
)
{
if
(
color
)
{
result
=
d3
[
'
scale
'
+
scale
](
d3
[
color
])
result
=
d3
[
'
scale
'
+
scale
](
d3
[
color
])
.
domain
(
domain
)
.
domain
(
domain
)
...
...
test/test-mapviewer-drilldown.html
View file @
1a892a7d
...
@@ -54,7 +54,7 @@
...
@@ -54,7 +54,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
TOT_P
'
,
metric
:
'
TOT_P
'
,
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
function
(
properties
)
{
tooltip
:
function
(
properties
)
{
return
properties
[
'
ST_NM
'
]
return
properties
[
'
ST_NM
'
]
...
@@ -73,7 +73,7 @@
...
@@ -73,7 +73,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
DT_CEN_CD
'
,
metric
:
'
DT_CEN_CD
'
,
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
function
(
properties
)
{
tooltip
:
function
(
properties
)
{
return
'
DISTRICT:
'
+
properties
[
'
DISTRICT
'
]
return
'
DISTRICT:
'
+
properties
[
'
DISTRICT
'
]
...
@@ -89,7 +89,7 @@
...
@@ -89,7 +89,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
TOT_P
'
,
metric
:
'
TOT_P
'
,
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
function
(
properties
)
{
tooltip
:
function
(
properties
)
{
return
'
<h5 style="background-color: yellow;"> VILLAGE:
'
+
properties
[
'
NAME
'
]
+
'
</h5>
'
return
'
<h5 style="background-color: yellow;"> VILLAGE:
'
+
properties
[
'
NAME
'
]
+
'
</h5>
'
...
...
test/test-mapviewer-tooltip.html
View file @
1a892a7d
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
'
just some tooltip text test
'
tooltip
:
'
just some tooltip text test
'
}
}
...
@@ -74,7 +74,7 @@
...
@@ -74,7 +74,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
score
'
,
metric
:
'
score
'
,
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
function
(
d
)
{
tooltip
:
function
(
d
)
{
return
d
.
ST_NM
+
'
:
'
+
d
.
score
return
d
.
ST_NM
+
'
:
'
+
d
.
score
...
@@ -97,7 +97,7 @@
...
@@ -97,7 +97,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
tooltip
:
function
(
d
)
{
tooltip
:
function
(
d
)
{
return
'
just some tooltip text test
'
+
d
.
name
return
'
just some tooltip text test
'
+
d
.
name
...
...
test/test-mapviewer.html
View file @
1a892a7d
...
@@ -43,6 +43,8 @@
...
@@ -43,6 +43,8 @@
<div
id=
"marker-map"
style=
"height:300px"
></div>
<div
id=
"marker-map"
style=
"height:300px"
></div>
<script>
<script>
// TODO: write test case to see if properties are merged for choropleth?
// TODO: circle markers mergedata functions properly
var
marker_map
=
g1
.
mapviewer
({
var
marker_map
=
g1
.
mapviewer
({
id
:
'
marker-map
'
,
id
:
'
marker-map
'
,
layers
:
{
layers
:
{
...
@@ -105,13 +107,10 @@
...
@@ -105,13 +107,10 @@
url
:
'
cities.json
'
,
url
:
'
cities.json
'
,
latitude
:
'
lat
'
,
latitude
:
'
lat
'
,
longitude
:
'
long
'
,
longitude
:
'
long
'
,
options
:
{
title
:
'
column-name
'
// TODO: implement as popup,
},
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
metric
:
function
(
row
)
{
return
row
[
'
pollution
'
]
+
row
[
'
crimes
'
]
},
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
}
}
}
}
}
}
...
@@ -124,6 +123,7 @@
...
@@ -124,6 +123,7 @@
circle_svg
.
each
(
function
()
{
circle_svg
.
each
(
function
()
{
circle_fill
.
push
(
$
(
this
).
attr
(
'
fill
'
))
circle_fill
.
push
(
$
(
this
).
attr
(
'
fill
'
))
})
})
console
.
log
(
"
check
"
,
circle_fill
,
new
Set
(
circle_fill
))
// tests if all colors are distinct
// tests if all colors are distinct
test
.
equals
(
circle_fill
.
length
,
(
new
Set
(
circle_fill
)).
size
)
test
.
equals
(
circle_fill
.
length
,
(
new
Set
(
circle_fill
)).
size
)
test
.
end
()
test
.
end
()
...
@@ -154,10 +154,18 @@
...
@@ -154,10 +154,18 @@
dataKey
:
'
name
'
,
dataKey
:
'
name
'
,
mapKey
:
'
ST_NM
'
mapKey
:
'
ST_NM
'
},
},
options
:
{
style
:
{
fillColor
:
'
#ccc
'
,
fillOpacity
:
0.9
}
},
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
TOT_P
'
,
metric
:
'
score
'
,
// same as function(d) { return d.age }
range
:
'
RdYlGn
'
scale
:
'
linear
'
,
domain
:
[
10
,
15
,
30
],
range
:
[
'
red
'
,
'
yellow
'
,
'
green
'
],
}
}
}
}
}
}
...
@@ -230,7 +238,7 @@
...
@@ -230,7 +238,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
TOT_P
'
,
metric
:
'
TOT_P
'
,
range
:
'
RdYlGn
'
scheme
:
'
Viridis
'
},
},
weight
:
{
weight
:
{
metric
:
'
P_06
'
,
metric
:
'
P_06
'
,
...
@@ -250,7 +258,7 @@
...
@@ -250,7 +258,7 @@
attrs
:
{
attrs
:
{
fillColor
:
{
fillColor
:
{
metric
:
'
pollution
'
,
metric
:
'
pollution
'
,
range
:
'
RdYlGn
'
,
scheme
:
'
Viridis
'
,
domain
:
[
0
,
500
]
domain
:
[
0
,
500
]
},
},
weight
:
{
weight
:
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment