Skip to content
Snippets Groups Projects
Commit 51aee5a2 authored by Tom Robinson's avatar Tom Robinson
Browse files

Cache cardinalities in a weak map instead of mutating potentially immutable column object.

parent 96c14055
No related branches found
No related tags found
No related merge requests found
......@@ -6,11 +6,19 @@ import EventEmitter from "events";
let events = new EventEmitter();
type ParamsMap = { [key:string]: any };
type TransformFn = (o: any) => any;
function makeMethod(method: string, hasBody: boolean = false) {
return function(
urlTemplate: string,
params: { [key:string]: any } = {}
params: ParamsMap|TransformFn = {},
transformResponse: TransformFn = (o) => o
) {
if (typeof params === "function") {
transformResponse = params;
params = {};
}
return function(
data: { [key:string]: any },
options: { [key:string]: any } = {}
......@@ -54,7 +62,7 @@ function makeMethod(method: string, hasBody: boolean = false) {
let body = xhr.responseText;
try { body = JSON.parse(body); } catch (e) {}
if (xhr.status >= 200 && xhr.status <= 299) {
resolve(body);
resolve(transformResponse(body));
} else {
reject({
status: xhr.status,
......
......@@ -6,7 +6,8 @@ import {
getChartTypeFromData,
DIMENSION_DIMENSION_METRIC,
DIMENSION_METRIC,
DIMENSION_METRIC_METRIC
DIMENSION_METRIC_METRIC,
getColumnCardinality
} from "metabase/visualizations/lib/utils";
import { isNumeric, isDate, isMetric, isDimension, isLatitude, isLongitude, hasLatitudeAndLongitudeColumns } from "metabase/lib/schema_metadata";
......@@ -73,7 +74,7 @@ function getDefaultLineAreaBarColumns([{ data: { cols, rows } }]) {
if (isDate(dimensions[1]) && !isDate(dimensions[0])) {
// if the series dimension is a date but the axis dimension is not then swap them
dimensions.reverse();
} else if (dimensions[1].cardinality > dimensions[0].cardinality) {
} else if (getColumnCardinality(cols, rows, 1) > getColumnCardinality(cols, rows, 0)) {
// if the series dimension is higher cardinality than the axis dimension then swap them
dimensions.reverse();
}
......
/* @flow */
export type Timestamp = string;
export type ColumnName = string;
// TODO: incomplete
export type Column = {
name: ColumnName,
display_name: string,
base_type: string
}
export type Row = Array<string|number|Timestamp>
export type Dataset = {
data: {
cols: Column[],
columns: ColumnName[],
rows: Row[]
}
}
......@@ -3,6 +3,8 @@ import React from "react";
import _ from "underscore";
import d3 from "d3";
import crossfilter from "crossfilter";
import * as colors from "metabase/lib/colors";
const SPLIT_AXIS_UNSPLIT_COST = -100;
......@@ -160,7 +162,6 @@ export function colorShade(hex, shade = 0) {
}
import { isDimension, isMetric } from "metabase/lib/schema_metadata";
import crossfilter from "crossfilter";
export const DIMENSION_METRIC = "DIMENSION_METRIC";
export const DIMENSION_METRIC_METRIC = "DIMENSION_METRIC_METRIC";
......@@ -184,24 +185,24 @@ export const isDimensionMetricMetric = (cols, strict = true) =>
isDimension(cols[0]) &&
cols.slice(1).reduce((acc, col) => acc && isMetric(col), true)
// cache computed cardinalities in a weak map since they are computationally expensive
const cardinalityCache = new WeakMap();
function computeColumnCardinality(cols, rows) {
let dataset = crossfilter(rows);
for (const [index, col] of Object.entries(cols)) {
if (col.cardinality == null) {
col.cardinality = dataset.dimension(d => d[index]).group().size();
}
export function getColumnCardinality(cols, rows, index) {
const col = cols[index];
if (!cardinalityCache.has(col)) {
let dataset = crossfilter(rows);
cardinalityCache.set(col, dataset.dimension(d => d[index]).group().size())
}
return cardinalityCache.get(col);
}
export function getChartTypeFromData(cols, rows, strict = true) {
computeColumnCardinality(cols, rows);
// this should take precendence for backwards compatibilty
if (isDimensionMetricMetric(cols, strict)) {
return DIMENSION_METRIC_METRIC;
} else if (isDimensionDimensionMetric(cols, strict)) {
if (cols[0].cardinality < MAX_SERIES || cols[1].cardinality < MAX_SERIES) {
if (getColumnCardinality(cols, rows, 0) < MAX_SERIES || getColumnCardinality(cols, rows, 1) < MAX_SERIES) {
return DIMENSION_DIMENSION_METRIC;
}
} else if (isDimensionMetric(cols, strict)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment