diff --git a/src/client/components/facet_results/Deck.js b/src/client/components/facet_results/Deck.js index 0aaf8fb59abb140faae921a5606d16a5daecd508..c70abb78a1f85ba06a4d2e35da497ba0c326e846 100644 --- a/src/client/components/facet_results/Deck.js +++ b/src/client/components/facet_results/Deck.js @@ -2,7 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import { withStyles } from '@material-ui/core/styles' import DeckGL from '@deck.gl/react' -import { ArcLayer } from '@deck.gl/layers' +import { ArcLayer, PolygonLayer } from '@deck.gl/layers' import { HeatmapLayer, HexagonLayer } from '@deck.gl/aggregation-layers' import ReactMapGL, { NavigationControl, FullscreenControl, HTMLOverlay } from 'react-map-gl' import DeckArcLayerLegend from './DeckArcLayerLegend' @@ -189,99 +189,122 @@ class Deck extends React.Component { } */ }) - render () { - const { classes, mapBoxAccessToken, mapBoxStyle, layerType, fetching, results, showTooltips } = this.props - const { hoverInfo } = this.state - const showTooltip = showTooltips && hoverInfo && hoverInfo.object - const hasData = !fetching && results && results.length > 0 && - ((results[0].lat && results[0].long) || (results[0].from && results[0].to)) + createPolygonLayer = data => + new PolygonLayer({ + id: 'polygon-layer', + data, + extruded: false, + pickable: true, + stroked: true, + filled: true, + wireframe: false, + lineWidthMinPixels: 1, + getPolygon: d => d.polygon, + getFillColor: d => [255, 255, 0, 255], + getLineColor: [80, 80, 80], + getLineWidth: 1 + }) + + render () { + const { classes, mapBoxAccessToken, mapBoxStyle, layerType, fetching, results, showTooltips } = this.props + const { hoverInfo } = this.state + const showTooltip = showTooltips && hoverInfo && hoverInfo.object + const hasData = !fetching && results && results.length > 0 && + ( + (results[0].lat && results[0].long) || + (results[0].from && results[0].to) || + results[0].polygon + ) - /* It's OK to create a new Layer instance on every render + /* It's OK to create a new Layer instance on every render https://github.com/uber/deck.gl/blob/master/docs/developer-guide/using-layers.md#should-i-be-creating-new-layers-on-every-render - */ - let layer = null - if (hasData) { - switch (layerType) { - case 'arcLayer': - layer = this.createArcLayer(results) - break - case 'heatmapLayer': - layer = this.createHeatmapLayer(results) - break - case 'hexagonLayer': - layer = this.createHexagonLayer(results) - break - default: - layer = this.createHeatmapLayer(results) - break + */ + let layer = null + if (hasData) { + switch (layerType) { + case 'arcLayer': + layer = this.createArcLayer(results) + break + case 'heatmapLayer': + layer = this.createHeatmapLayer(results) + break + case 'hexagonLayer': + layer = this.createHexagonLayer(results) + break + case 'polygonLayer': + layer = this.createPolygonLayer(results) + break + default: + layer = this.createHeatmapLayer(results) + break + } } - } - return ( - <div className={classes.root}> - <ReactMapGL - {...this.state.viewport} - width='100%' - height='100%' - reuseMaps - mapStyle={`mapbox://styles/mapbox/${mapBoxStyle}`} - preventStyleDiffing - mapboxApiAccessToken={mapBoxAccessToken} - onViewportChange={this.handleOnViewportChange} - > - <div className={classes.navigationContainer}> - <NavigationControl /> - <FullscreenControl - className={classes.fullscreenButton} - container={document.querySelector('mapboxgl-map')} + return ( + <div className={classes.root}> + <ReactMapGL + {...this.state.viewport} + width='100%' + height='100%' + reuseMaps + mapStyle={`mapbox://styles/mapbox/${mapBoxStyle}`} + preventStyleDiffing + mapboxApiAccessToken={mapBoxAccessToken} + onViewportChange={this.handleOnViewportChange} + > + <div className={classes.navigationContainer}> + <NavigationControl /> + <FullscreenControl + className={classes.fullscreenButton} + container={document.querySelector('mapboxgl-map')} + /> + </div> + {layerType === 'arcLayer' && + <HTMLOverlay redraw={() => + <DeckArcLayerLegend + title={this.props.legendTitle} + fromText={this.props.legendFromText} + toText={this.props.legendToText} + />} + />} + <DeckGL + viewState={this.state.viewport} + layers={[layer]} + getCursor={() => 'initial'} /> - </div> - {layerType === 'arcLayer' && - <HTMLOverlay redraw={() => - <DeckArcLayerLegend - title={this.props.legendTitle} - fromText={this.props.legendFromText} - toText={this.props.legendToText} + {this.renderSpinner()} + {layerType === 'arcLayer' && this.props.instanceAnalysisData && this.state.dialog.open && + <DeckArcLayerDialog + onClose={this.closeDialog.bind(this)} + data={this.props.instanceAnalysisData} + from={this.state.dialog.from} + to={this.state.dialog.to} + fromText={this.props.fromText} + toText={this.props.toText} + countText={this.props.countText} + listHeadingSingleInstance={this.props.listHeadingSingleInstance} + listHeadingMultipleInstances={this.props.listHeadingMultipleInstances} + instanceVariable={[this.props.instanceVariable]} + resultClass={this.props.resultClass} + facetClass={this.props.facetClass} />} - />} - <DeckGL - viewState={this.state.viewport} - layers={[layer]} - getCursor={() => 'initial'} - /> - {this.renderSpinner()} - {layerType === 'arcLayer' && this.props.instanceAnalysisData && this.state.dialog.open && - <DeckArcLayerDialog - onClose={this.closeDialog.bind(this)} - data={this.props.instanceAnalysisData} - from={this.state.dialog.from} - to={this.state.dialog.to} - fromText={this.props.fromText} - toText={this.props.toText} - countText={this.props.countText} - listHeadingSingleInstance={this.props.listHeadingSingleInstance} - listHeadingMultipleInstances={this.props.listHeadingMultipleInstances} - instanceVariable={[this.props.instanceVariable]} - resultClass={this.props.resultClass} - facetClass={this.props.facetClass} - />} - {layerType === 'arcLayer' && showTooltip && - <DeckArcLayerTooltip - data={hoverInfo} - fromText={this.props.fromText} - toText={this.props.toText} - countText={this.props.countText} - showMoreText={this.props.showMoreText} - />} - </ReactMapGL> - </div> - ) - } + {layerType === 'arcLayer' && showTooltip && + <DeckArcLayerTooltip + data={hoverInfo} + fromText={this.props.fromText} + toText={this.props.toText} + countText={this.props.countText} + showMoreText={this.props.showMoreText} + />} + </ReactMapGL> + </div> + ) + } } Deck.propTypes = { classes: PropTypes.object.isRequired, results: PropTypes.array, - layerType: PropTypes.oneOf(['arcLayer', 'heatmapLayer', 'hexagonLayer']), + layerType: PropTypes.oneOf(['arcLayer', 'heatmapLayer', 'hexagonLayer', 'polygonLayer']), tooltips: PropTypes.bool, mapBoxAccessToken: PropTypes.string.isRequired, mapBoxStyle: PropTypes.string.isRequired, diff --git a/src/client/components/perspectives/sampo/Perspective1.js b/src/client/components/perspectives/sampo/Perspective1.js index f5ad37b674e8c20511d062bdac89b3de54b2799b..10b2a3151afc0589f2a7e60f02e2de065e9a8b3f 100644 --- a/src/client/components/perspectives/sampo/Perspective1.js +++ b/src/client/components/perspectives/sampo/Perspective1.js @@ -220,7 +220,7 @@ const Perspective1 = props => { fetchInstanceAnalysis={props.fetchInstanceAnalysis} fetching={props.perspectiveState.fetching} fetchingInstanceAnalysisData={props.perspectiveState.fetchingInstanceAnalysisData} - layerType='arcLayer' + layerType='polygonLayer' mapBoxAccessToken={MAPBOX_ACCESS_TOKEN} mapBoxStyle={MAPBOX_STYLE} layoutConfig={props.layoutConfig} diff --git a/src/client/reducers/sampo/perspective1.js b/src/client/reducers/sampo/perspective1.js index 89cc1faed2df1673b0afe75ba7f26f732dbd8d79..f6d24d75e8ab13a38d95a9e1a201138d5cf75221 100644 --- a/src/client/reducers/sampo/perspective1.js +++ b/src/client/reducers/sampo/perspective1.js @@ -291,7 +291,8 @@ const resultClasses = new Set([ 'manuscriptInstancePageNetwork', 'manuscriptFacetResultsNetwork', 'perspective1KnowledgeGraphMetadata', - 'speechesByYearAndParty' + 'speechesByYearAndParty', + 'choropleth' ]) const perspective1 = (state = INITIAL_STATE, action) => { diff --git a/src/server/sparql/Mappers.js b/src/server/sparql/Mappers.js index ca8acdb532f216d79a1852900129474fb455d102..ab80565e423d748e04f00f544a150b522eecc2a0 100644 --- a/src/server/sparql/Mappers.js +++ b/src/server/sparql/Mappers.js @@ -268,11 +268,6 @@ export const toBarChartRaceFormat = ({ data, config }) => { resultObj[i] = null } } - // const initialItem = cloneDeep(resultObj[lastKey]) - // for (const key in initialItem) { - // initialItem[key].value = 0 - // } - // resultObj[firstKey - step] = initialItem return resultObj } @@ -310,3 +305,19 @@ const mergeDataItems = (itemA, itemB) => { } return merged } + +export const toPolygonLayerFormat = ({ data, config }) => { + const scaledData = linearScale({ data, config }) + scaledData.forEach(item => { + const pointArray = item.polygon.split(' ') + const deckGlArray = pointArray.map(point => { + const latLng = point.split(',') + return [ + parseFloat(latLng[1]).toFixed(4), + parseFloat(latLng[0]).toFixed(4) + ] + }) + item.polygon = deckGlArray + }) + return scaledData +} diff --git a/src/server/sparql/sampo/BackendSearchConfig.js b/src/server/sparql/sampo/BackendSearchConfig.js index 749d7a2499e7a0273bace5bb7cbd35bd381d40a1..245aeae09ae119f9f614d50df292cd701e44404e 100644 --- a/src/server/sparql/sampo/BackendSearchConfig.js +++ b/src/server/sparql/sampo/BackendSearchConfig.js @@ -66,7 +66,8 @@ import { mapLineChart, mapMultipleLineChart, linearScale, - toBarChartRaceFormat + toBarChartRaceFormat, + toPolygonLayerFormat } from '../Mappers' export const backendSearchConfig = { @@ -174,7 +175,7 @@ export const backendSearchConfig = { q: choroplethQuery, resultMapper: makeObjectList, postprocess: { - func: linearScale, + func: toPolygonLayerFormat, config: { variable: 'instanceCount', minAllowed: 0, diff --git a/src/server/sparql/sampo/sparql_queries/SparqlQueriesPerspective1.js b/src/server/sparql/sampo/sparql_queries/SparqlQueriesPerspective1.js index 213da13a9f17e18b962774ddf651f5094dc2b0f8..41cb01837163a21c25640e8c1a2e2c302384c20c 100644 --- a/src/server/sparql/sampo/sparql_queries/SparqlQueriesPerspective1.js +++ b/src/server/sparql/sampo/sparql_queries/SparqlQueriesPerspective1.js @@ -601,11 +601,11 @@ export const choroplethQuery = ` SELECT ?id ?prefLabel ?polygon (count(?death) as ?instanceCount) WHERE { ?id a <http://www.yso.fi/onto/suo/kunta> ; - skos:prefLabel ?prefLabel . - # sch:polygon ?polygon + skos:prefLabel ?prefLabel ; + sch:polygon ?polygon . ?death crm-org:P7_took_place_at ?id . } GROUP BY ?id ?prefLabel ?polygon ORDER BY desc(?instanceCount) - LIMIT 10 + LIMIT 1 `