mirror of
https://github.com/heavyai/heavyai-charting.git
synced 2026-02-01 16:00:04 +00:00
fix color lookup for popup
click filtering fix examples push layer filter to chart filter handlers; filter null values from popup rewrite query to use table aliases for self-join change query to use non-join when tables are the same improved click filtering fix race between mapbox style load and data fetch layer filter listeners import d3
This commit is contained in:
parent
dd15c167c3
commit
afc4f50838
@ -1,38 +1,27 @@
|
||||
document.addEventListener("DOMContentLoaded", function init() {
|
||||
var config = {
|
||||
table: "contributions_donotmodify",
|
||||
valueColumn: "contributions_donotmodify.amount",
|
||||
joinColumn: "contributions_donotmodify.contributor_zipcode",
|
||||
valueColumn: "amount",
|
||||
joinColumn: "contributor_zipcode",
|
||||
polyTable: "zipcodes",
|
||||
polyJoinColumn: "ZCTA5CE10",
|
||||
timeColumn: "contrib_date",
|
||||
timeLabel: "Number of Contributions",
|
||||
domainBoundMin: 0,
|
||||
domainBoundMax: 2600,
|
||||
domainBoundMin: 1,
|
||||
domainBoundMax: 2600, //00000,
|
||||
numTimeBins: 423
|
||||
}
|
||||
|
||||
new MapdCon()
|
||||
.protocol("http")
|
||||
.host("kali.mapd.com")
|
||||
.port("9092")
|
||||
.protocol("https")
|
||||
.host("metis.mapd.com")
|
||||
.port("443")
|
||||
.dbName("mapd")
|
||||
.user("mapd")
|
||||
.password("HyperInteractive")
|
||||
.connect(function(error, con) {
|
||||
crossfilter
|
||||
.crossfilter(
|
||||
con,
|
||||
["contributions_donotmodify", "zipcodes"],
|
||||
[
|
||||
{
|
||||
table1: "contributions_donotmodify",
|
||||
attr1: "contributor_zipcode",
|
||||
table2: "zipcodes",
|
||||
attr2: "ZCTA5CE10"
|
||||
}
|
||||
]
|
||||
)
|
||||
.crossfilter(con, "contributions_donotmodify")
|
||||
.then(function(cf) {
|
||||
crossfilter
|
||||
.crossfilter(con, "contributions_donotmodify")
|
||||
@ -48,12 +37,12 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
var parent = document.getElementById("polymap")
|
||||
// The values in the table and column specified in crossFilter.dimension
|
||||
// must correspond to values in the table and keysColumn specified in polyRasterChart.polyJoin.
|
||||
var dim = crossFilter.dimension("zipcodes.rowid") // Values to join on.
|
||||
var grp = dim
|
||||
.group()
|
||||
.reduceAvg("contributions_donotmodify.amount", "avgContrib") // Values to color on.
|
||||
// var dim = crossFilter.dimension("tweets_nov_feb.state_abbr") // Values to join on.
|
||||
// var grp = dim.group().reduceAvg("tweets_nov_feb.tweet_count") // Values to color on.
|
||||
var dim = crossFilter.dimension(config.joinColumn) // Values to join on.
|
||||
// var grp = dim
|
||||
// .group()
|
||||
// .reduceAvg("contributions_donotmodify.amount", "avgContrib") // Values to color on.
|
||||
// // var dim = crossFilter.dimension("tweets_nov_feb.state_abbr") // Values to join on.
|
||||
// // var grp = dim.group().reduceAvg("tweets_nov_feb.tweet_count") // Values to color on.
|
||||
|
||||
// Can use getDomainBounds to dynamically find min and max of values that will be colored,
|
||||
// or the domain [min, max] can be set directly
|
||||
@ -93,15 +82,16 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
var polyLayer = dc
|
||||
.rasterLayer("polys")
|
||||
.crossfilter(crossFilter)
|
||||
.dimension(dim)
|
||||
.setState({
|
||||
data: [
|
||||
{
|
||||
table: "contributions_donotmodify",
|
||||
attr: "contributor_zipcode"
|
||||
table: config.table,
|
||||
attr: config.joinColumn
|
||||
},
|
||||
{
|
||||
table: "zipcodes",
|
||||
attr: "ZCTA5CE10"
|
||||
table: config.polyTable,
|
||||
attr: config.polyJoinColumn
|
||||
}
|
||||
],
|
||||
mark: {
|
||||
@ -114,45 +104,48 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
encoding: {
|
||||
color: {
|
||||
type: "quantitative",
|
||||
aggregrate: "AVG(contributions_donotmodify.amount)",
|
||||
aggregrate: `SUM(${config.valueColumn})`,
|
||||
domain: colorDomain,
|
||||
range: colorRange
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
polyLayer.popupColumns(["color"])
|
||||
polyLayer.popupColumns(["key0", "color"])
|
||||
polyLayer.popupColumnsMapped({"key0": "zipcode", "color": "total amount"})
|
||||
|
||||
polyMap.pushLayer("polys", polyLayer).init().then(() => {
|
||||
// polyMap.borderWidth(zoomToBorderWidth(polyMap.map().getZoom()))
|
||||
// Keeps the border widths reasonable regardless of zoom level.
|
||||
polyMap.map().on("zoom", function() {
|
||||
polyMap
|
||||
.pushLayer("polys", polyLayer)
|
||||
.init()
|
||||
.then(() => {
|
||||
// polyMap.borderWidth(zoomToBorderWidth(polyMap.map().getZoom()))
|
||||
// Keeps the border widths reasonable regardless of zoom level.
|
||||
polyMap.map().on("zoom", function() {
|
||||
// polyMap.borderWidth(zoomToBorderWidth(polyMap.map().getZoom()))
|
||||
})
|
||||
|
||||
dc.renderAllAsync()
|
||||
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
_.debounce(function() {
|
||||
resizeChart(polyMap, 1.5)
|
||||
}, 500)
|
||||
)
|
||||
})
|
||||
|
||||
dc.renderAllAsync()
|
||||
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
_.debounce(function() {
|
||||
resizeChart(polyMap, 1.5)
|
||||
}, 500)
|
||||
)
|
||||
})
|
||||
|
||||
// hover effect with popup
|
||||
var debouncedPopup = _.debounce(displayPopupWithData, 250)
|
||||
polyMap.map().on('mousewheel', polyMap.hidePopup);
|
||||
polyMap.map().on('wheel', polyMap.hidePopup);
|
||||
polyMap.map().on('mousemove', polyMap.hidePopup);
|
||||
polyMap.map().on('mousemove', debouncedPopup);
|
||||
function displayPopupWithData (event) {
|
||||
polyMap.map().on("mousewheel", polyMap.hidePopup)
|
||||
polyMap.map().on("wheel", polyMap.hidePopup)
|
||||
polyMap.map().on("mousemove", polyMap.hidePopup)
|
||||
polyMap.map().on("mousemove", debouncedPopup)
|
||||
function displayPopupWithData(event) {
|
||||
polyMap.getClosestResult(event.point, polyMap.displayPopup)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function getDomainBounds(column, groupAll, callback) {
|
||||
groupAll
|
||||
.reduce([
|
||||
@ -237,7 +230,10 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
chart.map().resize()
|
||||
chart.isNodeAnimate = false
|
||||
}
|
||||
chart.width(width()).height(height() / heightDivisor).renderAsync()
|
||||
chart
|
||||
.width(width())
|
||||
.height(height() / heightDivisor)
|
||||
.renderAsync()
|
||||
dc.redrawAllAsync()
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +134,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
domain: langDomain,
|
||||
range: langOriginColors
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
})
|
||||
.popupColumns(['tweet_text', 'sender_name', 'tweet_time', 'lang', 'origin', 'followers'])
|
||||
|
||||
@ -115,6 +115,11 @@
|
||||
domain: langDomain,
|
||||
range: langColors
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
})
|
||||
.xDim(xDim)
|
||||
|
||||
@ -79,11 +79,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
// get the dimensions used for the first layer, the polygon layer
|
||||
// we need the rowid for polygon rendering, so the dimension will be based on
|
||||
// the rowid of the zipcodes
|
||||
var polyDim1 = polycfLayer1.dimension("zipcodes.rowid");
|
||||
var polyDim1 = polycfLayer1.dimension("contributions_donotmodify.amount");
|
||||
|
||||
// we're going to color based on the average contribution of the zipcode,
|
||||
// so reduce the average from the join
|
||||
var polyGrp1 = polyDim1.group().reduceAvg("contributions_donotmodify.amount", "avgContrib");
|
||||
// var polyGrp1 = polyDim1.group().reduceAvg("contributions_donotmodify.amount", "avgContrib");
|
||||
|
||||
// create the scale to use for the fill color of the polygons.
|
||||
// We're going to use the avg contribution of the zipcode to color the poly.
|
||||
@ -99,6 +99,7 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
// setup the first layer, the zipcode polygons
|
||||
var polyLayer1 = dc.rasterLayer("polys")
|
||||
.crossfilter(polycfLayer1)
|
||||
.dimension(polyDim1)
|
||||
.setState({
|
||||
data: [
|
||||
{
|
||||
@ -131,8 +132,8 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
}
|
||||
}
|
||||
})
|
||||
.popupColumns(['color', 'ZCTA5CE10'])
|
||||
.popupColumnsMapped({color: "avg contribution", ZCTA5CE10: 'zipcode'})
|
||||
.popupColumns(['color', 'key0'])
|
||||
.popupColumnsMapped({color: "avg contribution", key0: 'zipcode'})
|
||||
|
||||
/*-----------BUILD LAYER #2, POINTS OF TWEETS-------------*/
|
||||
/*-----SIZED BY # OF FOLLOWERS AND COLORED BY LANGUAGE----*/
|
||||
@ -201,6 +202,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
title: "tweets[lang]"
|
||||
}
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
})
|
||||
.popupColumns(['tweet_text', 'sender_name', 'tweet_time', 'lang', 'origin', 'followers'])
|
||||
@ -266,6 +272,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
title: "contributions[recipient_party]"
|
||||
}
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
})
|
||||
// for point layers
|
||||
|
||||
@ -77,7 +77,7 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
// get the dimensions used for the first layer, the polygon layer
|
||||
// we need the rowid for polygon rendering, so the dimension will be based on
|
||||
// the rowid of the zipcodes
|
||||
var polyDim1 = polycfLayer1.dimension("zipcodes.rowid");
|
||||
var polyDim1 = polycfLayer1.dimension("contributor_zipcode");
|
||||
|
||||
// we're going to color based on the average contribution of the zipcode,
|
||||
// so reduce the average from the join
|
||||
@ -97,6 +97,7 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
// setup the first layer, the zipcode polygons
|
||||
var polyLayer1 = dc.rasterLayer("polys")
|
||||
.crossfilter(polycfLayer1)
|
||||
.dimension(polyDim1)
|
||||
.setState({
|
||||
data: [
|
||||
{
|
||||
@ -205,6 +206,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
domain: langDomain,
|
||||
range: langColors
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
}) // of a tweet is not found in the domain fo the scale
|
||||
.popupColumns(['tweet_text', 'sender_name', 'tweet_time', 'lang', 'origin', 'followers'])
|
||||
@ -269,6 +275,11 @@ document.addEventListener("DOMContentLoaded", function init() {
|
||||
domain: ["D", "R"],
|
||||
range: ["blue", "red"]
|
||||
}
|
||||
},
|
||||
config: {
|
||||
point: {
|
||||
shape: "circle"
|
||||
}
|
||||
}
|
||||
})
|
||||
.xDim(xDim3)
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -13,7 +13,7 @@
|
||||
}
|
||||
},
|
||||
"@mapd/crossfilter": {
|
||||
"version": "git://github.com/mapd/mapd-crossfilter.git#9340d15de829dc91a42cef74d5beec35462774b3",
|
||||
"version": "git://github.com/mapd/mapd-crossfilter.git#9bdeae1012f97eecc0bc1fa86420049e38a76799",
|
||||
"dev": true
|
||||
},
|
||||
"@mapd/mapd-draw": {
|
||||
@ -6682,10 +6682,10 @@
|
||||
"resolved": "https://registry.npmjs.org/mapbox-gl-supported/-/mapbox-gl-supported-1.2.0.tgz",
|
||||
"integrity": "sha1-y9NN+JQgbK3amjPI2aRgnya7GYk="
|
||||
},
|
||||
"mapd-data-layer": {
|
||||
"version": "0.0.4-rc.2",
|
||||
"resolved": "https://registry.npmjs.org/mapd-data-layer/-/mapd-data-layer-0.0.4-rc.2.tgz",
|
||||
"integrity": "sha512-zYjfG0FGG+K6+/jpZF0iULDJcQoT5wpm/YJW2X9qVQrgTa2aGbXWEOCmN6dNCP4MeGNdAVOqfn2dkaAd0M0Vsg==",
|
||||
"mapd-data-layer-2": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mapd-data-layer-2/-/mapd-data-layer-2-0.0.1.tgz",
|
||||
"integrity": "sha1-4zhejliwdPKcCG47ATUIHatDvEg=",
|
||||
"requires": {
|
||||
"invariant": "2.2.2"
|
||||
}
|
||||
|
||||
@ -58,14 +58,14 @@
|
||||
"http-server": "^0.11.1",
|
||||
"legendables": "git://github.com/mapd/legendables.git#d678a36de78b008814fab72ce260ee33ee7d48b7",
|
||||
"mapbox-gl": "https://github.com/mapd/mapbox-gl-js/tarball/9c04de6949fe498c8c79f5c0627dfd6d6321f307",
|
||||
"mapd-data-layer": "0.0.4-rc.2",
|
||||
"mapd-data-layer-2": "0.0.1",
|
||||
"moment": "2.13.0",
|
||||
"ramda": "0.21.0",
|
||||
"simplify-js": "^1.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mapd/connector": "git://github.com/mapd/mapd-connector.git#v2.0.0",
|
||||
"@mapd/crossfilter": "git://github.com/mapd/mapd-crossfilter.git#v1.1.0",
|
||||
"@mapd/crossfilter": "git://github.com/mapd/mapd-crossfilter.git#tai/poly-stuff",
|
||||
"atob": "^2.0.3",
|
||||
"babel-cli": "^6.10.1",
|
||||
"babel-core": "^6.10.4",
|
||||
|
||||
@ -811,6 +811,10 @@ body {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.map-polygon-shape {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
|
||||
.map-popup, .map-point-wrap {
|
||||
width: 100%;
|
||||
|
||||
@ -450,6 +450,10 @@ export default function rasterChart(parent, useMap, chartGroup, _mapboxgl) {
|
||||
} else {
|
||||
_chart._setOverlay(null, null, null, browser, Boolean(redraw))
|
||||
}
|
||||
} else {
|
||||
_chart.map().once("style.load", () => {
|
||||
_chart._doRender(data, redraw, doNotForceData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -585,6 +585,18 @@ export default function mapMixin(
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
_map.on("mousedown", event => {
|
||||
_chart.getClosestResult(event.point, result => {
|
||||
const data = result.row_set[0]
|
||||
_chart.getLayerNames().forEach(layerName => {
|
||||
const layer = _chart.getLayer(layerName)
|
||||
if (typeof layer.onClick === "function") {
|
||||
layer.onClick(_chart, data, event.originalEvent)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ export function rasterDrawMixin(chart) {
|
||||
let currYRange = null
|
||||
const coordFilters = new Map()
|
||||
let origFilterFunc = null
|
||||
let origFilterAll = null
|
||||
|
||||
const defaultStyle = {
|
||||
fillColor: "#22a7f0",
|
||||
@ -281,9 +282,9 @@ export function rasterDrawMixin(chart) {
|
||||
function filters() {
|
||||
const shapes = drawEngine.getShapesAsJSON()
|
||||
if (shapes[0]) {
|
||||
return chart.zoomFilters().concat(Array.from(shapes))
|
||||
return chart.nonDrawFilters().concat(Array.from(shapes))
|
||||
}
|
||||
return chart.zoomFilters()
|
||||
return chart.nonDrawFilters()
|
||||
}
|
||||
|
||||
function filter(filterArg) {
|
||||
@ -442,11 +443,19 @@ export function rasterDrawMixin(chart) {
|
||||
chart.map().on("resize", updateDrawResize)
|
||||
|
||||
origFilterFunc = chart.filter
|
||||
origFilterAll = chart.filterAll
|
||||
chart.filter = filter
|
||||
chart.zoomFilters = chart.filters
|
||||
chart.nonDrawFilters = chart.filters
|
||||
chart.filters = filters
|
||||
|
||||
chart.filterAll = () => {
|
||||
origFilterAll()
|
||||
chart.getLayerNames().forEach(layerName => {
|
||||
const layer = chart.getLayer(layerName)
|
||||
if (layer.hasOwnProperty("filterAll")) {
|
||||
layer.filterAll()
|
||||
}
|
||||
})
|
||||
if (coordFilters) {
|
||||
coordFilters.forEach(filterObj => {
|
||||
filterObj.shapeFilters = []
|
||||
|
||||
@ -3,6 +3,8 @@ import {
|
||||
createRasterLayerGetterSetter,
|
||||
createVegaAttrMixin
|
||||
} from "../utils/utils-vega"
|
||||
import d3 from "d3"
|
||||
import { events } from "../core/events"
|
||||
import { parser } from "../utils/utils"
|
||||
|
||||
const vegaLineJoinOptions = ["miter", "round", "bevel"]
|
||||
@ -49,6 +51,7 @@ function validateMiterLimit(newMiterLimit, currMiterLimit) {
|
||||
|
||||
export default function rasterLayerPolyMixin(_layer) {
|
||||
_layer.crossfilter = createRasterLayerGetterSetter(_layer, null)
|
||||
_layer.filtersInverse = createRasterLayerGetterSetter(_layer, false)
|
||||
|
||||
createVegaAttrMixin(
|
||||
_layer,
|
||||
@ -91,18 +94,54 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
return state
|
||||
}
|
||||
|
||||
function getTransforms({ filter, globalFilter }) {
|
||||
function getTransforms({
|
||||
filter,
|
||||
globalFilter,
|
||||
layerFilter = [],
|
||||
filtersInverse
|
||||
}) {
|
||||
const selfJoin = state.data[0].table === state.data[1].table
|
||||
|
||||
const groupby = {
|
||||
type: "project",
|
||||
expr: `${state.data[0].table}.${state.data[0].attr}`,
|
||||
as: "key0"
|
||||
}
|
||||
|
||||
const transforms = [
|
||||
{
|
||||
type: "rowid",
|
||||
table: state.data[1].table
|
||||
},
|
||||
!selfJoin && {
|
||||
type: "filter",
|
||||
expr: `${state.data[0].table}.${state.data[0].attr} = ${
|
||||
state.data[1].table
|
||||
}.${state.data[1].attr}`
|
||||
},
|
||||
{
|
||||
type: "aggregate",
|
||||
fields: [parser.parseExpression(state.encoding.color.aggregrate)],
|
||||
fields: [
|
||||
layerFilter.length
|
||||
? parser.parseExpression({
|
||||
type: "case",
|
||||
cond: [
|
||||
[
|
||||
{
|
||||
type: filtersInverse ? "not in" : "in",
|
||||
expr: `${state.data[0].table}.${state.data[0].attr}`,
|
||||
set: layerFilter
|
||||
},
|
||||
parser.parseExpression(state.encoding.color.aggregrate)
|
||||
]
|
||||
],
|
||||
else: null
|
||||
})
|
||||
: parser.parseExpression(state.encoding.color.aggregrate)
|
||||
],
|
||||
ops: [null],
|
||||
as: ["color"],
|
||||
groupby: {
|
||||
type: "project",
|
||||
expr: state.data[0].attr,
|
||||
as: "key0"
|
||||
}
|
||||
groupby
|
||||
}
|
||||
]
|
||||
|
||||
@ -130,7 +169,13 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
return transforms
|
||||
}
|
||||
|
||||
_layer.__genVega = function({ filter, globalFilter, layerName }) {
|
||||
_layer.__genVega = function({
|
||||
filter,
|
||||
globalFilter,
|
||||
layerFilter,
|
||||
filtersInverse,
|
||||
layerName
|
||||
}) {
|
||||
const colorRange = state.encoding.color.range.map(c =>
|
||||
adjustOpacity(c, state.encoding.color.opacity)
|
||||
)
|
||||
@ -138,14 +183,18 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
data: {
|
||||
name: layerName,
|
||||
format: "polys",
|
||||
shapeColGroup: "mapd",
|
||||
sql: parser.writeSQL({
|
||||
type: "root",
|
||||
source: state.data[0].table, // .map(source => source.table).join(", "),
|
||||
transform: getTransforms({ filter, globalFilter })
|
||||
}),
|
||||
dbTableName: state.data[1].table,
|
||||
polysKey: state.data[1].attr
|
||||
source: [
|
||||
...new Set(state.data.map((source, index) => source.table))
|
||||
].join(", "),
|
||||
transform: getTransforms({
|
||||
filter,
|
||||
globalFilter,
|
||||
layerFilter,
|
||||
filtersInverse
|
||||
})
|
||||
})
|
||||
},
|
||||
scales: [
|
||||
{
|
||||
@ -153,7 +202,8 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
type: "quantize",
|
||||
domain: state.encoding.color.domain,
|
||||
range: colorRange,
|
||||
nullValue: "#CACACA"
|
||||
nullValue: "#D6D7D6",
|
||||
default: "#D6D7D6"
|
||||
}
|
||||
],
|
||||
mark: {
|
||||
@ -177,7 +227,7 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
strokeColor:
|
||||
typeof state.mark === "object" ? state.mark.strokeColor : "white",
|
||||
strokeWidth:
|
||||
typeof state.mark === "object" ? state.mark.strokeWidth : 0,
|
||||
typeof state.mark === "object" ? state.mark.strokeWidth : 0.5,
|
||||
lineJoin:
|
||||
typeof state.mark === "object" ? state.mark.lineJoin : "miter",
|
||||
miterLimit:
|
||||
@ -195,8 +245,12 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
_layer._genVega = function(chart, layerName, group, query) {
|
||||
_vega = _layer.__genVega({
|
||||
layerName,
|
||||
filter: _layer.crossfilter().getFilterString(),
|
||||
globalFilter: _layer.crossfilter().getGlobalFilterString()
|
||||
filter: _layer
|
||||
.crossfilter()
|
||||
.getFilterString(_layer.dimension().getDimensionIndex()),
|
||||
globalFilter: _layer.crossfilter().getGlobalFilterString(),
|
||||
layerFilter: _layer.filters(),
|
||||
filtersInverse: _layer.filtersInverse()
|
||||
})
|
||||
return _vega
|
||||
}
|
||||
@ -240,6 +294,41 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
return false
|
||||
}
|
||||
|
||||
let _filtersArray = []
|
||||
const _isInverseFilter = false
|
||||
const polyLayerEvents = ["filtered"]
|
||||
const _listeners = d3.dispatch.apply(d3, polyLayerEvents)
|
||||
|
||||
_layer.filter = function(key, isInverseFilter) {
|
||||
if (isInverseFilter !== _layer.filtersInverse()) {
|
||||
_layer.filterAll()
|
||||
_layer.filtersInverse(isInverseFilter)
|
||||
}
|
||||
if (_filtersArray.includes(key)) {
|
||||
_filtersArray = _filtersArray.filter(v => v !== key)
|
||||
} else {
|
||||
_filtersArray = [..._filtersArray, key]
|
||||
}
|
||||
_filtersArray.length
|
||||
? _layer
|
||||
.dimension()
|
||||
.filterMulti(_filtersArray, undefined, isInverseFilter)
|
||||
: _layer.dimension().filterAll()
|
||||
}
|
||||
|
||||
_layer.filters = function() {
|
||||
return _filtersArray
|
||||
}
|
||||
|
||||
_layer.filterAll = function() {
|
||||
_filtersArray = []
|
||||
}
|
||||
|
||||
_layer.on = function(event, listener) {
|
||||
_listeners.on(event, listener)
|
||||
return _layer
|
||||
}
|
||||
|
||||
_layer._displayPopup = function(
|
||||
chart,
|
||||
parentElem,
|
||||
@ -443,9 +532,13 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
scale * (pts[i + 1] - bounds[2]) +
|
||||
", ")
|
||||
}
|
||||
pointStr = pointStr.slice(0, pointStr.length - 2)
|
||||
pointStr = pointStr.slice(0, pointStr.length - 2).replace(/NaN/g, "")
|
||||
|
||||
group.append("polygon").attr("points", pointStr)
|
||||
group
|
||||
.append("polygon")
|
||||
.attr("points", pointStr)
|
||||
.attr("class", "map-polygon-shape")
|
||||
.on("click", () => _layer.onClick(chart, data, d3.event))
|
||||
})
|
||||
|
||||
_scaledPopups[chart] = isScaled
|
||||
@ -458,6 +551,21 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
}
|
||||
}
|
||||
|
||||
_layer.onClick = function(chart, data, event) {
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
const isInverseFilter = Boolean(event && (event.metaKey || event.ctrlKey))
|
||||
|
||||
chart.hidePopup()
|
||||
events.trigger(() => {
|
||||
_layer.filter(data.key0, isInverseFilter)
|
||||
chart.filter(data.key0, isInverseFilter)
|
||||
_listeners.filtered(_layer, _filtersArray)
|
||||
chart.redrawGroup()
|
||||
})
|
||||
}
|
||||
|
||||
_layer._hidePopup = function(chart, hideCallback) {
|
||||
const mapPoly = chart.select(".map-poly")
|
||||
if (mapPoly) {
|
||||
@ -479,6 +587,7 @@ export default function rasterLayerPolyMixin(_layer) {
|
||||
}
|
||||
|
||||
_layer._destroyLayer = function(chart) {
|
||||
_layer.on("filtered", null)
|
||||
// deleteCanvas(chart)
|
||||
}
|
||||
|
||||
|
||||
@ -82,19 +82,17 @@ describe("rasterLayerPolyMixin", () => {
|
||||
data: {
|
||||
name: "polys",
|
||||
format: "polys",
|
||||
shapeColGroup: "mapd",
|
||||
sql:
|
||||
"SELECT zipcodes.rowid, AVG(contributions_donotmodify.amount) as color FROM contributions_donotmodify, zipcodes WHERE (contributions_donotmodify.contributor_zipcode = zipcodes.ZCTA5CE10) AND (amount=0) GROUP BY zipcodes.rowid ORDER BY color LIMIT 1000000"
|
||||
"SELECT zipcodes.rowid, contributions_donotmodify.contributor_zipcode as key0, AVG(contributions_donotmodify.amount) as color FROM contributions_donotmodify, zipcodes WHERE (contributions_donotmodify.contributor_zipcode = zipcodes.ZCTA5CE10) AND (amount=0) GROUP BY zipcodes.rowid, key0 LIMIT 1000000"
|
||||
},
|
||||
scales: [
|
||||
{
|
||||
name: "polys_fillColor",
|
||||
type: "linear",
|
||||
type: "quantize",
|
||||
domain: [0, 100],
|
||||
range: ["black", "blue"],
|
||||
default: "green",
|
||||
nullValue: "#CACACA",
|
||||
clamp: false
|
||||
nullValue: "#D6D7D6",
|
||||
default: "#D6D7D6"
|
||||
}
|
||||
],
|
||||
mark: {
|
||||
|
||||
@ -332,7 +332,7 @@ export default function rasterLayer(layerType) {
|
||||
function renderPopupHTML(data, columnOrder, columnMap) {
|
||||
let html = ""
|
||||
columnOrder.forEach(key => {
|
||||
if (!data[key] && !columnMap[key]) {
|
||||
if (typeof data[key] === "undefined" || data[key] === null) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createParser } from "mapd-data-layer"
|
||||
import { createParser } from "mapd-data-layer-2"
|
||||
import { formatDataValue, maybeFormatInfinity } from "./formatting-helpers"
|
||||
|
||||
import { DAYS, HOURS, MONTHS, QUARTERS } from "../constants/dates-and-times"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user