Skip to content
Snippets Groups Projects
Unverified Commit c4ab8329 authored by Alexander Lesnenko's avatar Alexander Lesnenko Committed by GitHub
Browse files

Allow using Grid map in native questies questions (#17930)

* Fix grid map is not rendered for native questions

* add check for map button
parent 6d440668
Branches
Tags
No related merge requests found
......@@ -31,12 +31,7 @@ export const rangeForValue = (
value: Value,
column: ?Column,
): ?[number, number] => {
if (
typeof value === "number" &&
column &&
column.binning_info &&
column.binning_info.bin_width
) {
if (typeof value === "number" && column?.binning_info?.bin_width) {
return [value, value + column.binning_info.bin_width];
}
};
......
......@@ -105,6 +105,8 @@ const ChartTypeOption = ({
borderRadius: 10,
padding: 12,
}}
data-testid={`${visualization.uiName}-button`}
data-is-sensible={isSensible}
>
<Icon name={visualization.iconName} size={20} />
</Flex>
......
......@@ -3,10 +3,32 @@ import L from "leaflet";
import { t } from "ttag";
import d3 from "d3";
import { rangeForValue } from "metabase/lib/dataset";
import { color } from "metabase/lib/colors";
import { rangeForValue } from "metabase/lib/dataset";
import { isNumeric, isMetric } from "metabase/lib/schema_metadata";
import { computeNumericDataInverval } from "../lib/numeric";
const isValidCoordinatesColumn = column =>
column.binning_info || (column.source === "native" && isNumeric(column));
const computeValueRange = (value, values) => [
value,
value + computeNumericDataInverval(values),
];
const getValueRange = (value, column, values) => {
const binningBasedResult = rangeForValue(value, column);
return binningBasedResult || computeValueRange(value, values);
};
export default class LeafletGridHeatMap extends LeafletMap {
static isSensible({ cols }) {
return (
cols.filter(isValidCoordinatesColumn).length >= 2 &&
cols.filter(isMetric).length > 0
);
}
componentDidMount() {
super.componentDidMount();
......@@ -22,10 +44,15 @@ export default class LeafletGridHeatMap extends LeafletMap {
const { points, min, max } = this.props;
const { latitudeColumn, longitudeColumn } = this._getLatLonColumns();
if (!latitudeColumn.binning_info || !longitudeColumn.binning_info) {
if (
!isValidCoordinatesColumn(latitudeColumn) ||
!isValidCoordinatesColumn(longitudeColumn)
) {
throw new Error(t`Grid map requires binned longitude/latitude.`);
}
const { latitudeIndex, longitudeIndex } = this._getLatLonIndexes();
const colorScale = d3.scale
.linear()
.domain([min, max])
......@@ -34,7 +61,13 @@ export default class LeafletGridHeatMap extends LeafletMap {
const gridSquares = gridLayer.getLayers();
const totalSquares = Math.max(points.length, gridSquares.length);
const latitudeValues = points.map(row => row[latitudeIndex]);
const longitureValues = points.map(row => row[longitudeIndex]);
for (let i = 0; i < totalSquares; i++) {
const [latitude, longiture, metric] = points[i];
if (i >= points.length) {
gridLayer.removeLayer(gridSquares[i]);
}
......@@ -45,9 +78,19 @@ export default class LeafletGridHeatMap extends LeafletMap {
}
if (i < points.length) {
gridSquares[i].setStyle({ color: colorScale(points[i][2]) });
const [latMin, latMax] = rangeForValue(points[i][0], latitudeColumn);
const [lonMin, lonMax] = rangeForValue(points[i][1], longitudeColumn);
gridSquares[i].setStyle({ color: colorScale(metric) });
const [latMin, latMax] = getValueRange(
latitude,
latitudeColumn,
latitudeValues,
);
const [lonMin, lonMax] = getValueRange(
longiture,
longitudeColumn,
longitureValues,
);
gridSquares[i].setBounds([[latMin, lonMin], [latMax, lonMax]]);
}
}
......
......@@ -5,6 +5,7 @@ import ChoroplethMap, {
getColorplethColorScale,
} from "../components/ChoroplethMap";
import PinMap from "../components/PinMap";
import LeafletGridHeatMap from "../components/LeafletGridHeatMap";
import { ChartSettingsError } from "metabase/visualizations/lib/errors";
import {
......@@ -46,7 +47,8 @@ export default class Map extends Component {
static isSensible({ cols, rows }) {
return (
PinMap.isSensible({ cols, rows }) ||
ChoroplethMap.isSensible({ cols, rows })
ChoroplethMap.isSensible({ cols, rows }) ||
LeafletGridHeatMap.isSensible({ cols, rows })
);
}
......
......@@ -185,4 +185,39 @@ describe("scenarios > visualizations > maps", () => {
cy.findByText("Longitude:");
cy.findByText("1");
});
it("should render grid map visualization for native questions (metabase#8362)", () => {
visitQuestionAdhoc({
dataset_query: {
type: "native",
native: {
query: `
select 20 as "Latitude", -110 as "Longitude", 1 as "metric" union all
select 70 as "Latitude", -170 as "Longitude", 5 as "metric"
`,
"template-tags": {},
},
database: 1,
},
display: "map",
visualization_settings: {
"map.type": "grid",
"map.latitude_column": "Latitude",
"map.longitude_column": "Longitude",
"map.metric_column": "metric",
},
});
// Ensure chart is rendered
cy.get(".leaflet-interactive");
cy.findByText("Visualization").click();
// Ensure the Map visualization is sensible
cy.findByTestId("Map-button").should(
"have.attr",
"data-is-sensible",
"true",
);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment