mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
feat: make polygon support geojson feature and fix autozoom (#11)
* feat: support standard geojson feature in polygon * fix: viewport autozoom * fix: type * fix: lint * refactor: renames * fix: travis * build: add yarn.lock * fix: travis * fix: error message * fix: storybook * fix: improt * fix: address comments * fix: storybook * fix: remove yarn.lock * refactor: viewport * fix: extension * fix: extension
This commit is contained in:
parent
1a93f58550
commit
940e449bbe
@ -50,7 +50,7 @@ webpack.config.js
|
|||||||
# Lock files, libs should not have lock files
|
# Lock files, libs should not have lock files
|
||||||
npm-shrinkwrap.json
|
npm-shrinkwrap.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
|
||||||
old-yarn.lock
|
old-yarn.lock
|
||||||
.*.swp
|
.*.swp
|
||||||
_gh-pages
|
_gh-pages
|
||||||
|
# Now only allow yarn.lock
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/d3-array": "^2.0.0",
|
||||||
"bootstrap-slider": "^10.0.0",
|
"bootstrap-slider": "^10.0.0",
|
||||||
"d3-array": "^1.2.4",
|
"d3-array": "^1.2.4",
|
||||||
"d3-color": "^1.2.0",
|
"d3-color": "^1.2.0",
|
||||||
@ -41,7 +42,7 @@
|
|||||||
"react-map-gl": "^4.0.10",
|
"react-map-gl": "^4.0.10",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
"urijs": "^1.18.10",
|
"urijs": "^1.18.10",
|
||||||
"viewport-mercator-project": "^6.1.1"
|
"@math.gl/web-mercator": "^3.1.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@superset-ui/chart": "^0.12.0",
|
"@superset-ui/chart": "^0.12.0",
|
||||||
|
@ -32,7 +32,8 @@ import Legend from './components/Legend';
|
|||||||
import { hexToRGB } from './utils/colors';
|
import { hexToRGB } from './utils/colors';
|
||||||
import { getPlaySliderParams } from './utils/time';
|
import { getPlaySliderParams } from './utils/time';
|
||||||
import sandboxedEval from './utils/sandbox';
|
import sandboxedEval from './utils/sandbox';
|
||||||
import { fitViewport } from './layers/common';
|
// eslint-disable-next-line import/extensions
|
||||||
|
import fitViewport from './utils/fitViewport';
|
||||||
|
|
||||||
const { getScale } = CategoricalColorNamespace;
|
const { getScale } = CategoricalColorNamespace;
|
||||||
|
|
||||||
@ -119,9 +120,15 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
|
|||||||
|
|
||||||
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
||||||
|
|
||||||
const viewport = props.formData.autozoom
|
const { width, height, formData } = props;
|
||||||
? fitViewport(props.viewport, props.getPoints(features))
|
let { viewport } = props;
|
||||||
: props.viewport;
|
if (formData.autozoom) {
|
||||||
|
viewport = fitViewport(viewport, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
points: props.getPoints(features),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start,
|
start,
|
||||||
|
@ -26,7 +26,8 @@ import { isEqual } from 'lodash';
|
|||||||
|
|
||||||
import DeckGLContainer from './DeckGLContainer';
|
import DeckGLContainer from './DeckGLContainer';
|
||||||
import CategoricalDeckGLContainer from './CategoricalDeckGLContainer';
|
import CategoricalDeckGLContainer from './CategoricalDeckGLContainer';
|
||||||
import { fitViewport } from './layers/common';
|
// eslint-disable-next-line import/extensions
|
||||||
|
import fitViewport from './utils/fitViewport';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
formData: PropTypes.object.isRequired,
|
formData: PropTypes.object.isRequired,
|
||||||
@ -48,10 +49,17 @@ export function createDeckGLComponent(getLayer, getPoints) {
|
|||||||
class Component extends React.PureComponent {
|
class Component extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const originalViewport = props.viewport;
|
|
||||||
const viewport = props.formData.autozoom
|
const { width, height, formData } = props;
|
||||||
? fitViewport(originalViewport, getPoints(props.payload.data.features))
|
let { viewport } = props;
|
||||||
: originalViewport;
|
if (formData.autozoom) {
|
||||||
|
viewport = fitViewport(viewport, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
points: getPoints(props.payload.data.features),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
viewport,
|
viewport,
|
||||||
layer: this.computeLayer(props),
|
layer: this.computeLayer(props),
|
||||||
|
@ -31,16 +31,16 @@ import Legend from '../../components/Legend';
|
|||||||
import TooltipRow from '../../TooltipRow';
|
import TooltipRow from '../../TooltipRow';
|
||||||
import { getBuckets, getBreakPointColorScaler } from '../../utils';
|
import { getBuckets, getBreakPointColorScaler } from '../../utils';
|
||||||
|
|
||||||
import { commonLayerProps, fitViewport } from '../common';
|
import { commonLayerProps } from '../common';
|
||||||
import { getPlaySliderParams } from '../../utils/time';
|
import { getPlaySliderParams } from '../../utils/time';
|
||||||
import sandboxedEval from '../../utils/sandbox';
|
import sandboxedEval from '../../utils/sandbox';
|
||||||
|
// eslint-disable-next-line import/extensions
|
||||||
|
import getPointsFromPolygon from '../../utils/getPointsFromPolygon';
|
||||||
|
// eslint-disable-next-line import/extensions
|
||||||
|
import fitViewport from '../../utils/fitViewport';
|
||||||
|
|
||||||
const DOUBLE_CLICK_TRESHOLD = 250; // milliseconds
|
const DOUBLE_CLICK_TRESHOLD = 250; // milliseconds
|
||||||
|
|
||||||
function getPoints(features) {
|
|
||||||
return features.flatMap(d => d.polygon);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getElevation(d, colorScaler) {
|
function getElevation(d, colorScaler) {
|
||||||
/* in deck.gl 5.3.4 (used in Superset as of 2018-10-24), if a polygon has
|
/* in deck.gl 5.3.4 (used in Superset as of 2018-10-24), if a polygon has
|
||||||
* opacity zero it will make everything behind it have opacity zero,
|
* opacity zero it will make everything behind it have opacity zero,
|
||||||
@ -114,7 +114,7 @@ export function getLayer(formData, payload, onAddFilter, setTooltip, selected, o
|
|||||||
pickable: true,
|
pickable: true,
|
||||||
filled: fd.filled,
|
filled: fd.filled,
|
||||||
stroked: fd.stroked,
|
stroked: fd.stroked,
|
||||||
getPolygon: d => d.polygon,
|
getPolygon: getPointsFromPolygon,
|
||||||
getFillColor: colorScaler,
|
getFillColor: colorScaler,
|
||||||
getLineColor: [sc.r, sc.g, sc.b, 255 * sc.a],
|
getLineColor: [sc.r, sc.g, sc.b, 255 * sc.a],
|
||||||
getLineWidth: fd.line_width,
|
getLineWidth: fd.line_width,
|
||||||
@ -154,26 +154,32 @@ class DeckGLPolygon extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getDerivedStateFromProps(props, state) {
|
static getDerivedStateFromProps(props, state) {
|
||||||
|
const { width, height, formData, payload } = props;
|
||||||
|
|
||||||
// the state is computed only from the payload; if it hasn't changed, do
|
// the state is computed only from the payload; if it hasn't changed, do
|
||||||
// not recompute state since this would reset selections and/or the play
|
// not recompute state since this would reset selections and/or the play
|
||||||
// slider position due to changes in form controls
|
// slider position due to changes in form controls
|
||||||
if (state && props.payload.form_data === state.formData) {
|
if (state && payload.form_data === state.formData) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const features = props.payload.data.features || [];
|
const features = payload.data.features || [];
|
||||||
const timestamps = features.map(f => f.__timestamp);
|
const timestamps = features.map(f => f.__timestamp);
|
||||||
|
|
||||||
// the granularity has to be read from the payload form_data, not the
|
// the granularity has to be read from the payload form_data, not the
|
||||||
// props formData which comes from the instantaneous controls state
|
// props formData which comes from the instantaneous controls state
|
||||||
const granularity =
|
const granularity = payload.form_data.time_grain_sqla || payload.form_data.granularity || 'P1D';
|
||||||
props.payload.form_data.time_grain_sqla || props.payload.form_data.granularity || 'P1D';
|
|
||||||
|
|
||||||
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
||||||
|
|
||||||
const viewport = props.formData.autozoom
|
let { viewport } = props;
|
||||||
? fitViewport(props.viewport, getPoints(features))
|
if (formData.autozoom) {
|
||||||
: props.viewport;
|
viewport = fitViewport(viewport, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
points: features.flatMap(getPointsFromPolygon),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start,
|
start,
|
||||||
@ -184,7 +190,7 @@ class DeckGLPolygon extends React.Component {
|
|||||||
viewport,
|
viewport,
|
||||||
selected: [],
|
selected: [],
|
||||||
lastClick: 0,
|
lastClick: 0,
|
||||||
formData: props.payload.form_data,
|
formData: payload.form_data,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,10 @@ import { t } from '@superset-ui/translation';
|
|||||||
import AnimatableDeckGLContainer from '../../AnimatableDeckGLContainer';
|
import AnimatableDeckGLContainer from '../../AnimatableDeckGLContainer';
|
||||||
import { getPlaySliderParams } from '../../utils/time';
|
import { getPlaySliderParams } from '../../utils/time';
|
||||||
import sandboxedEval from '../../utils/sandbox';
|
import sandboxedEval from '../../utils/sandbox';
|
||||||
import { commonLayerProps, fitViewport } from '../common';
|
import { commonLayerProps } from '../common';
|
||||||
import TooltipRow from '../../TooltipRow';
|
import TooltipRow from '../../TooltipRow';
|
||||||
|
// eslint-disable-next-line import/extensions
|
||||||
|
import fitViewport from '../../utils/fitViewport';
|
||||||
|
|
||||||
function getPoints(data) {
|
function getPoints(data) {
|
||||||
return data.map(d => d.position);
|
return data.map(d => d.position);
|
||||||
@ -123,10 +125,16 @@ class DeckGLScreenGrid extends React.PureComponent {
|
|||||||
props.payload.form_data.time_grain_sqla || props.payload.form_data.granularity || 'P1D';
|
props.payload.form_data.time_grain_sqla || props.payload.form_data.granularity || 'P1D';
|
||||||
|
|
||||||
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
const { start, end, getStep, values, disabled } = getPlaySliderParams(timestamps, granularity);
|
||||||
|
const { width, height, formData } = props;
|
||||||
|
|
||||||
const viewport = props.formData.autozoom
|
let { viewport } = props;
|
||||||
? fitViewport(props.viewport, getPoints(features))
|
if (formData.autozoom) {
|
||||||
: props.viewport;
|
viewport = fitViewport(viewport, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
points: getPoints(features),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start,
|
start,
|
||||||
|
@ -16,77 +16,9 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { fitBounds } from 'viewport-mercator-project';
|
|
||||||
import * as d3array from 'd3-array';
|
import * as d3array from 'd3-array';
|
||||||
import sandboxedEval from '../utils/sandbox';
|
import sandboxedEval from '../utils/sandbox';
|
||||||
|
|
||||||
const PADDING = 0.25;
|
|
||||||
const GEO_BOUNDS = {
|
|
||||||
LAT_MAX: 90,
|
|
||||||
LAT_MIN: -90,
|
|
||||||
LNG_MAX: 180,
|
|
||||||
LNG_MIN: -180,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the latitude bounds if latitude is a single coordinate
|
|
||||||
* @param latExt Latitude range
|
|
||||||
*/
|
|
||||||
function getLatBoundsForSingleCoordinate(latExt) {
|
|
||||||
const latMin =
|
|
||||||
latExt[0] - PADDING < GEO_BOUNDS.LAT_MIN ? GEO_BOUNDS.LAT_MIN : latExt[0] - PADDING;
|
|
||||||
const latMax =
|
|
||||||
latExt[1] + PADDING > GEO_BOUNDS.LAT_MAX ? GEO_BOUNDS.LAT_MAX : latExt[1] + PADDING;
|
|
||||||
|
|
||||||
return [latMin, latMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the longitude bounds if longitude is a single coordinate
|
|
||||||
* @param lngExt Longitude range
|
|
||||||
*/
|
|
||||||
function getLngBoundsForSingleCoordinate(lngExt) {
|
|
||||||
const lngMin =
|
|
||||||
lngExt[0] - PADDING < GEO_BOUNDS.LNG_MIN ? GEO_BOUNDS.LNG_MIN : lngExt[0] - PADDING;
|
|
||||||
const lngMax =
|
|
||||||
lngExt[1] + PADDING > GEO_BOUNDS.LNG_MAX ? GEO_BOUNDS.LNG_MAX : lngExt[1] + PADDING;
|
|
||||||
|
|
||||||
return [lngMin, lngMax];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getBounds(points) {
|
|
||||||
const latExt = d3array.extent(points, d => d[1]);
|
|
||||||
const lngExt = d3array.extent(points, d => d[0]);
|
|
||||||
const latBounds = latExt[0] === latExt[1] ? getLatBoundsForSingleCoordinate(latExt) : latExt;
|
|
||||||
const lngBounds = lngExt[0] === lngExt[1] ? getLngBoundsForSingleCoordinate(lngExt) : lngExt;
|
|
||||||
|
|
||||||
return [
|
|
||||||
[lngBounds[0], latBounds[0]],
|
|
||||||
[lngBounds[1], latBounds[1]],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fitViewport(viewport, points, padding = 10) {
|
|
||||||
try {
|
|
||||||
const bounds = getBounds(points);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...viewport,
|
|
||||||
...fitBounds({
|
|
||||||
bounds,
|
|
||||||
height: viewport.height,
|
|
||||||
padding,
|
|
||||||
width: viewport.width,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
/* eslint no-console: 0 */
|
|
||||||
console.error('Could not auto zoom', error);
|
|
||||||
|
|
||||||
return viewport;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function commonLayerProps(formData, setTooltip, setTooltipContent, onSelect) {
|
export function commonLayerProps(formData, setTooltip, setTooltipContent, onSelect) {
|
||||||
const fd = formData;
|
const fd = formData;
|
||||||
let onHover;
|
let onHover;
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import { extent as d3Extent } from 'd3-array';
|
||||||
|
import { Point, Range } from './types';
|
||||||
|
|
||||||
|
const LAT_LIMIT: Range = [-90, 90];
|
||||||
|
const LNG_LIMIT: Range = [-180, 180];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand a coordinate range by `padding` and within limits, if needed
|
||||||
|
*/
|
||||||
|
function expandIfNeeded([curMin, curMax]: Range, [minBound, maxBound]: Range, padding = 0.25) {
|
||||||
|
return curMin < curMax
|
||||||
|
? [curMin, curMax]
|
||||||
|
: [Math.max(minBound, curMin - padding), Math.min(maxBound, curMax + padding)];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function computeBoundsFromPoints(points: Point[]) {
|
||||||
|
const latBounds = expandIfNeeded(d3Extent(points, (x: Point) => x[1]) as Range, LAT_LIMIT);
|
||||||
|
const lngBounds = expandIfNeeded(d3Extent(points, (x: Point) => x[0]) as Range, LNG_LIMIT);
|
||||||
|
return [
|
||||||
|
[lngBounds[0], latBounds[0]],
|
||||||
|
[lngBounds[1], latBounds[1]],
|
||||||
|
];
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import { fitBounds } from '@math.gl/web-mercator';
|
||||||
|
import computeBoundsFromPoints from './computeBoundsFromPoints';
|
||||||
|
import { Point } from './types';
|
||||||
|
|
||||||
|
type Viewport = {
|
||||||
|
longtitude: number;
|
||||||
|
latitude: number;
|
||||||
|
zoom: number;
|
||||||
|
bearing?: number;
|
||||||
|
pitch?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FitViewportOptions = {
|
||||||
|
points: Point[];
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
minExtent?: number;
|
||||||
|
maxZoom?: number;
|
||||||
|
offset?: [number, number];
|
||||||
|
padding?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function fitViewport(
|
||||||
|
originalViewPort: Viewport,
|
||||||
|
{ points, width, height, minExtent, maxZoom, offset, padding = 20 }: FitViewportOptions,
|
||||||
|
) {
|
||||||
|
const { bearing, pitch } = originalViewPort;
|
||||||
|
const bounds = computeBoundsFromPoints(points);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
...fitBounds({
|
||||||
|
bounds,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
minExtent,
|
||||||
|
maxZoom,
|
||||||
|
offset,
|
||||||
|
padding,
|
||||||
|
}),
|
||||||
|
bearing,
|
||||||
|
pitch,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Could not fit viewport', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalViewPort;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { Point } from './types';
|
||||||
|
|
||||||
|
/** Format originally used by the Polygon plugin */
|
||||||
|
type CustomPolygonFeature = {
|
||||||
|
polygon: Point[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format that is geojson standard
|
||||||
|
* https://geojson.org/geojson-spec.html
|
||||||
|
*/
|
||||||
|
type GeojsonPolygonFeature = {
|
||||||
|
polygon: {
|
||||||
|
type: 'Feature';
|
||||||
|
geometry: {
|
||||||
|
type: 'Polygon';
|
||||||
|
coordinates: Point[][];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function getPointsFromPolygon(
|
||||||
|
feature: CustomPolygonFeature | GeojsonPolygonFeature,
|
||||||
|
) {
|
||||||
|
return 'geometry' in feature.polygon ? feature.polygon.geometry.coordinates[0] : feature.polygon;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
// range and point actually have different value ranges
|
||||||
|
// and also are different concept-wise
|
||||||
|
|
||||||
|
export type Range = [number, number];
|
||||||
|
export type Point = [number, number];
|
@ -0,0 +1,38 @@
|
|||||||
|
import getPointsFromPolygon from '../../src/utils/getPointsFromPolygon';
|
||||||
|
|
||||||
|
describe('getPointsFromPolygon', () => {
|
||||||
|
it('handle original input', () => {
|
||||||
|
expect(
|
||||||
|
getPointsFromPolygon({
|
||||||
|
polygon: [
|
||||||
|
[1, 2],
|
||||||
|
[3, 4],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
).toEqual([
|
||||||
|
[1, 2],
|
||||||
|
[3, 4],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
it('handle geojson features', () => {
|
||||||
|
expect(
|
||||||
|
getPointsFromPolygon({
|
||||||
|
polygon: {
|
||||||
|
type: 'Feature',
|
||||||
|
geometry: {
|
||||||
|
type: 'Polygon',
|
||||||
|
coordinates: [
|
||||||
|
[
|
||||||
|
[1, 2],
|
||||||
|
[3, 4],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toEqual([
|
||||||
|
[1, 2],
|
||||||
|
[3, 4],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
declare module '@math.gl/web-mercator';
|
@ -3,6 +3,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SuperChart } from '@superset-ui/chart';
|
import { SuperChart } from '@superset-ui/chart';
|
||||||
import payload from './payload';
|
import payload from './payload';
|
||||||
|
import geojsonPayload from './geojsonPayload';
|
||||||
import dummyDatasource from '../../../shared/dummyDatasource';
|
import dummyDatasource from '../../../shared/dummyDatasource';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
@ -72,4 +73,52 @@ export default [
|
|||||||
storyName: 'Basic',
|
storyName: 'Basic',
|
||||||
storyPath: 'legacy-|preset-chart-deckgl|PolygonChartPlugin',
|
storyPath: 'legacy-|preset-chart-deckgl|PolygonChartPlugin',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
renderStory: () => (
|
||||||
|
<SuperChart
|
||||||
|
chartType="deck_polygon"
|
||||||
|
width={400}
|
||||||
|
height={400}
|
||||||
|
datasource={dummyDatasource}
|
||||||
|
queryData={geojsonPayload}
|
||||||
|
formData={{
|
||||||
|
datasource: '9__table',
|
||||||
|
viz_type: 'deck_polygon',
|
||||||
|
time_range: '+:+',
|
||||||
|
line_column: 'contour',
|
||||||
|
line_type: 'json',
|
||||||
|
adhoc_filters: [],
|
||||||
|
metric: 'count',
|
||||||
|
point_radius_fixed: { type: 'fix', value: 1000 },
|
||||||
|
row_limit: 10000,
|
||||||
|
reverse_long_lat: false,
|
||||||
|
filter_nulls: true,
|
||||||
|
mapbox_style: 'mapbox://styles/mapbox/light-v9',
|
||||||
|
viewport: {
|
||||||
|
longitude: 6.85236157047845,
|
||||||
|
latitude: 31.222656842808707,
|
||||||
|
zoom: 1,
|
||||||
|
bearing: 0,
|
||||||
|
pitch: 0,
|
||||||
|
},
|
||||||
|
autozoom: true,
|
||||||
|
fill_color_picker: { a: 1, b: 73, g: 65, r: 3 },
|
||||||
|
stroke_color_picker: { a: 1, b: 135, g: 122, r: 0 },
|
||||||
|
filled: true,
|
||||||
|
stroked: false,
|
||||||
|
extruded: true,
|
||||||
|
multiplier: 1,
|
||||||
|
line_width: 10,
|
||||||
|
linear_color_scheme: 'blue_white_yellow',
|
||||||
|
opacity: 80,
|
||||||
|
num_buckets: 5,
|
||||||
|
table_filter: false,
|
||||||
|
toggle_polygons: true,
|
||||||
|
legend_position: 'tr',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
storyName: 'Single Polygon in geojson format',
|
||||||
|
storyPath: 'legacy-|preset-chart-deckgl|PolygonChartPlugin',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
export default {
|
||||||
|
cache_key: '31946c4488d1899827d283b668d83281',
|
||||||
|
cached_dttm: '2020-03-04T22:40:59',
|
||||||
|
cache_timeout: 129600,
|
||||||
|
error: null,
|
||||||
|
form_data: {
|
||||||
|
datasource: '93829__table',
|
||||||
|
viz_type: 'deck_polygon',
|
||||||
|
url_params: {},
|
||||||
|
time_range_endpoints: ['inclusive', 'exclusive'],
|
||||||
|
granularity_sqla: null,
|
||||||
|
time_range: '100 years ago : ',
|
||||||
|
line_column: 'geometry',
|
||||||
|
line_type: 'json',
|
||||||
|
adhoc_filters: [
|
||||||
|
{
|
||||||
|
clause: 'WHERE',
|
||||||
|
expressionType: 'SIMPLE',
|
||||||
|
filterOptionName: '4ea1a468-43f9-45f0-9655-576d2ab04bc1',
|
||||||
|
comparator: '',
|
||||||
|
operator: 'IS NOT NULL',
|
||||||
|
subject: 'geometry',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
metric: 'count',
|
||||||
|
point_radius_fixed: {
|
||||||
|
type: 'fix',
|
||||||
|
value: 1000,
|
||||||
|
},
|
||||||
|
row_limit: 1000,
|
||||||
|
reverse_long_lat: false,
|
||||||
|
filter_nulls: true,
|
||||||
|
mapbox_style: 'mapbox://styles/mapbox/light-v9',
|
||||||
|
viewport: {
|
||||||
|
longitude: 6.85236157047845,
|
||||||
|
latitude: 31.222656842808707,
|
||||||
|
zoom: 1,
|
||||||
|
bearing: 0,
|
||||||
|
pitch: 0,
|
||||||
|
},
|
||||||
|
autozoom: true,
|
||||||
|
fill_color_picker: {
|
||||||
|
r: 0,
|
||||||
|
g: 122,
|
||||||
|
b: 135,
|
||||||
|
a: 1,
|
||||||
|
},
|
||||||
|
stroke_color_picker: {
|
||||||
|
r: 0,
|
||||||
|
g: 122,
|
||||||
|
b: 135,
|
||||||
|
a: 1,
|
||||||
|
},
|
||||||
|
filled: true,
|
||||||
|
stroked: false,
|
||||||
|
extruded: true,
|
||||||
|
multiplier: 1,
|
||||||
|
line_width: 10,
|
||||||
|
linear_color_scheme: 'blue_white_yellow',
|
||||||
|
opacity: 80,
|
||||||
|
num_buckets: 5,
|
||||||
|
table_filter: false,
|
||||||
|
toggle_polygons: true,
|
||||||
|
legend_position: 'tr',
|
||||||
|
legend_format: null,
|
||||||
|
js_columns: [],
|
||||||
|
where: '',
|
||||||
|
having: '',
|
||||||
|
having_filters: [],
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
col: 'geometry',
|
||||||
|
op: 'IS NOT NULL',
|
||||||
|
val: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
is_cached: true,
|
||||||
|
status: 'success',
|
||||||
|
stacktrace: null,
|
||||||
|
rowcount: 1,
|
||||||
|
data: {
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
count: 1,
|
||||||
|
polygon: {
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {},
|
||||||
|
geometry: {
|
||||||
|
type: 'Polygon',
|
||||||
|
coordinates: [
|
||||||
|
[
|
||||||
|
[-149.95132113447022, 61.1310423022678],
|
||||||
|
[-149.95386039742468, 61.12975642234931],
|
||||||
|
[-149.9529189574033, 61.128200857856946],
|
||||||
|
[-149.94943860572158, 61.12793112735274],
|
||||||
|
[-149.9468993514573, 61.12921688848983],
|
||||||
|
[-149.94784044016444, 61.1307724989074],
|
||||||
|
[-149.95132113447022, 61.1310423022678],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
__timestamp: null,
|
||||||
|
elevation: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
mapboxApiKey:
|
||||||
|
'pk.eyJ1IjoiZ2tlZWUiLCJhIjoiY2lvbmN5dXhtMDA4NXRybTJjZWU2ZHVxOSJ9.CJG_6Oz52y5yI5cr3Ct_aQ',
|
||||||
|
metricLabels: ['count'],
|
||||||
|
},
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user