Skip to content
Snippets Groups Projects
Commit 8ef639b4 authored by Allen Gilliland's avatar Allen Gilliland
Browse files

Merge pull request #1994 from metabase/multiseries_bug_fixes

Multiseries bug fixes
parents 32faed37 44e54c9b
No related branches found
No related tags found
No related merge requests found
......@@ -37,7 +37,7 @@ export default class AddSeriesModal extends Component {
badCards: {}
};
_.bindAll(this, "onSearchChange", "onDone", "filteredCards")
_.bindAll(this, "onSearchChange", "onDone", "filteredCards", "onRemoveSeries")
}
static propTypes = {
......@@ -98,10 +98,19 @@ export default class AddSeriesModal extends Component {
this.setState({ series: this.state.series.filter(c => c.id !== card.id) });
}
} catch (e) {
console.error("onCardChange", e)
console.error("onCardChange", e);
this.setState({
state: "incompatible",
badCards: { ...this.state.badCards, [card.id]: true }
});
setTimeout(() => this.setState({ state: null }), 2000);
}
}
onRemoveSeries(card) {
this.setState({ series: this.state.series.filter(c => c.id !== card.id) });
}
onDone() {
this.props.setDashCardAttributes({
id: this.props.dashcard.id,
......@@ -184,13 +193,14 @@ export default class AddSeriesModal extends Component {
return (
<div className="absolute top left bottom right flex">
<div className="flex flex-column flex-full">
<div className="flex-no-shrink h3 pl4 pt4 pb1 text-bold">Add data</div>
<div className="flex-no-shrink h3 pl4 pt4 pb1 text-bold">Edit data</div>
<div className="flex-full mx1 relative">
<Visualization
className="absolute top left bottom right"
series={series}
isDashboard={true}
isMultiseries={true}
onRemoveSeries={this.onRemoveSeries}
/>
{ this.state.state &&
<div className="absolute top left bottom right flex layout-centered" style={{ backgroundColor: "rgba(255,255,255,0.80)" }}>
......
......@@ -88,6 +88,7 @@ export default class Scalar extends Component {
isScalarSeries={true}
hovered={this.props.hovered}
onHoverChange={this.props.onHoverChange}
allowSplitAxis={false}
/>
);
}
......
......@@ -25,7 +25,7 @@ export default class ChartTooltip extends Component {
if (!hovered || !hovered.data || (pinToMouse ? !hovered.event : !hovered.element)) {
return <span className="hidden" />;
}
let s = series[hovered.seriesIndex || 0];
let s = series[hovered.seriesIndex] || series[0];
return (
<TooltipPopover
target={pinToMouse ? null : hovered.element}
......
......@@ -41,7 +41,7 @@ export default class LegendHeader extends Component {
}
render() {
const { series, hovered, onAddSeries, extraActions, onHoverChange } = this.props;
const { series, hovered, onAddSeries, onRemoveSeries, extraActions, onHoverChange } = this.props;
const showDots = series.length > 1;
const isNarrow = this.state.width < 150;
const showTitles = !showDots || !isNarrow;
......@@ -50,9 +50,10 @@ export default class LegendHeader extends Component {
let colors = getCardColors(series[0].card);
return (
<div className={cx(styles.LegendHeader, "Card-title m1 flex flex-no-shrink flex-row align-center")}>
{ series.map((s, index) =>
<LegendItem key={index} card={s.card} index={index} color={colors[index % colors.length]} showDots={showDots} showTitles={showTitles} muted={hoveredSeriesIndex != null && index !== hoveredSeriesIndex} onHoverChange={onHoverChange} />
)}
{ series.map((s, index) => [
<LegendItem key={index} card={s.card} index={index} color={colors[index % colors.length]} showDots={showDots} showTitles={showTitles} muted={hoveredSeriesIndex != null && index !== hoveredSeriesIndex} onHoverChange={onHoverChange} />,
onRemoveSeries && index > 0 && <Icon className="text-grey-2 flex-no-shrink mr1 cursor-pointer" name="close" width={12} height={12} onClick={() => onRemoveSeries(s.card)} />
])}
{ onAddSeries &&
<span className="DashCard-actions flex-no-shrink">
<AddSeriesItem onAddSeries={onAddSeries} showTitles={!isNarrow} />
......@@ -96,7 +97,7 @@ class LegendItem extends Component {
onMouseLeave={() => onHoverChange && onHoverChange(null, null, null) }
isEnabled={this.state.tooltipIsEnabled}
>
<a href={Urls.card(card.id)} className={cx(styles.LegendItem, "no-decoration h3 text-bold flex align-center", { mr1: showTitles, muted: muted })} style={{ overflowX: "hidden", flex: "0 1 auto" }}>
<a href={card.id && Urls.card(card.id)} className={cx(styles.LegendItem, "no-decoration h3 text-bold flex align-center", { mr1: showTitles, muted: muted })} style={{ overflowX: "hidden", flex: "0 1 auto" }}>
{showDots && <div className="flex-no-shrink inline-block circular" style={{width: 13, height: 13, margin: 4, marginRight: 8, backgroundColor: color}} />}
{showTitles && <div ref="title" style={{ overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" }}>{card.name}</div> }
</a>
......@@ -110,7 +111,7 @@ const AddSeriesItem = ({ onAddSeries, showTitles }) =>
<span className="flex-no-shrink circular bordered border-brand flex layout-centered" style={{ width: 20, height: 20, marginRight: 8 }}>
<Icon className="text-brand" name="add" width={10} height={10} />
</span>
{ showTitles && <span className="flex-no-shrink">Add data</span> }
{ showTitles && <span className="flex-no-shrink">Edit data</span> }
</a>
export default LegendHeader;
......@@ -27,13 +27,15 @@ export default class LineAreaBarChart extends Component {
}
static seriesAreCompatible(initialSeries, newSeries) {
// no bare rows
if (newSeries.card.dataset_query.query.aggregation[0] === "rows") {
return false;
}
// must have one and only one breakout
if (newSeries.card.dataset_query.query.breakout.length !== 1) {
return false;
if (newSeries.card.dataset_query.type === "query") {
// no bare rows
if (newSeries.card.dataset_query.query.aggregation[0] === "rows") {
return false;
}
// must have one and only one breakout
if (newSeries.card.dataset_query.query.breakout.length !== 1) {
return false;
}
}
return columnsAreCompatible(initialSeries.data.cols, newSeries.data.cols);
......@@ -54,6 +56,10 @@ export default class LineAreaBarChart extends Component {
isDashboard: PropTypes.bool
};
static defaultProps = {
allowSplitAxis: true
};
componentWillMount() {
this.transformSeries(this.props);
}
......@@ -110,7 +116,7 @@ export default class LineAreaBarChart extends Component {
}
render() {
let { hovered, isDashboard, onAddSeries, extraActions } = this.props;
let { hovered, isDashboard, onAddSeries, onRemoveSeries, extraActions, allowSplitAxis } = this.props;
let { series, isMultiseries } = this.state;
const chartType = this.constructor.identifier;
......@@ -121,6 +127,7 @@ export default class LineAreaBarChart extends Component {
<LegendHeader
series={series}
onAddSeries={isMultiseries ? undefined : onAddSeries}
onRemoveSeries={onRemoveSeries}
extraActions={extraActions}
hovered={hovered}
onHoverChange={this.props.onHoverChange}
......@@ -131,6 +138,7 @@ export default class LineAreaBarChart extends Component {
chartType={chartType}
series={series}
className="flex-full"
allowSplitAxis={isMultiseries ? false : allowSplitAxis}
/>
<ChartTooltip series={series} hovered={hovered} />
</div>
......
......@@ -462,7 +462,7 @@ export let CardRenderer = {
chart.render();
},
lineAreaBar(element, chartType, { series, onHoverChange, onRender, isScalarSeries }) {
lineAreaBar(element, chartType, { series, onHoverChange, onRender, isScalarSeries, allowSplitAxis }) {
const colors = getCardColors(series[0].card);
const isTimeseries = dimensionIsTimeseries(series[0].data);
......@@ -514,7 +514,12 @@ export let CardRenderer = {
xValues = dimension.group().all().map(d => d.key);
let yExtents = groups.map(group => d3.extent(group[0].all(), d => d.value));
yAxisSplit = computeSplit(yExtents);
if (allowSplitAxis) {
yAxisSplit = computeSplit(yExtents);
} else {
yAxisSplit = [series.map((s,i) => i)];
}
}
if (isScalarSeries) {
......
......@@ -123,8 +123,7 @@ export function colorShade(hex, shade = 0) {
let components = (match[1] != null ? match.slice(1,4) : match.slice(4,7)).map((d) => parseInt(d, 16))
let min = Math.min(...components);
let max = Math.max(...components);
return "#" + components.map(c => {
console.log(shade, c, min, max, c * (max - min) / max * shade);
return Math.round(min + (max - min) * shade * (c / 255)).toString(16)
}).join("");
return "#" + components.map(c =>
Math.round(min + (max - min) * shade * (c / 255)).toString(16)
).join("");
}
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