diff --git a/frontend/src/metabase/dashboard/components/DashCard.jsx b/frontend/src/metabase/dashboard/components/DashCard.jsx
index b24fd3a65369c5882233f8ab2d57214271d541df..0e9a9aca987eb11959df519613b268a2edc6ca85 100644
--- a/frontend/src/metabase/dashboard/components/DashCard.jsx
+++ b/frontend/src/metabase/dashboard/components/DashCard.jsx
@@ -34,6 +34,7 @@ export default class DashCard extends Component {
         parameterValues: PropTypes.object.isRequired,
         markNewCardSeen: PropTypes.func.isRequired,
         fetchCardData: PropTypes.func.isRequired,
+        navigateToNewCardFromDashboard: PropTypes.func.isRequired
     };
 
     async componentDidMount() {
@@ -60,7 +61,7 @@ export default class DashCard extends Component {
             isEditingParameter,
             onAddSeries,
             onRemove,
-            navigateToNewCard,
+            navigateToNewCardFromDashboard,
             metadata
         } = this.props;
 
@@ -134,8 +135,9 @@ export default class DashCard extends Component {
                     onUpdateVisualizationSettings={this.props.onUpdateVisualizationSettings}
                     replacementContent={isEditingParameter && <DashCardParameterMapper dashcard={dashcard} />}
                     metadata={metadata}
-                    onChangeCardAndRun={ navigateToNewCard ? (card: UnsavedCard) => {
-                        navigateToNewCard(card, dashcard)
+                    onChangeCardAndRun={ navigateToNewCardFromDashboard ? ({ nextCard, previousCard }) => {
+                        // navigateToNewCardFromDashboard needs `dashcard` for applying active filters to the query
+                        navigateToNewCardFromDashboard({ nextCard, previousCard, dashcard })
                     } : null}
                 />
             </div>
diff --git a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
index b1ab2839a3bd0217bec0f776911e6a6e99de07be..ce36abfd94c59470b0421a9600e69f82b3313f37 100644
--- a/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardGrid.jsx
@@ -193,7 +193,7 @@ export default class DashboardGrid extends Component {
                 onAddSeries={this.onDashCardAddSeries.bind(this, dc)}
                 onUpdateVisualizationSettings={this.props.onUpdateDashCardVisualizationSettings.bind(this, dc.id)}
                 onReplaceAllVisualizationSettings={this.props.onReplaceAllDashCardVisualizationSettings.bind(this, dc.id)}
-                navigateToNewCard={this.props.navigateToNewCard}
+                navigateToNewCardFromDashboard={this.props.navigateToNewCardFromDashboard}
                 metadata={this.props.metadata}
             />
         )
diff --git a/frontend/src/metabase/dashboard/dashboard.js b/frontend/src/metabase/dashboard/dashboard.js
index 2bff4047b2ccefd3e7a7b1d656efa228f65bacc1..24aebceb82f09b61cc71f0925de46df7259400ad 100644
--- a/frontend/src/metabase/dashboard/dashboard.js
+++ b/frontend/src/metabase/dashboard/dashboard.js
@@ -14,7 +14,7 @@ import { applyParameters, questionUrlWithParameters } from "metabase/meta/Card";
 import { getParametersBySlug } from "metabase/meta/Parameter";
 
 import type { DashboardWithCards, DashCard, DashCardId } from "metabase/meta/types/Dashboard";
-import type { UnsavedCard, Card, CardId } from "metabase/meta/types/Card";
+import type { Card, CardId } from "metabase/meta/types/Card";
 
 import Utils from "metabase/lib/utils";
 import { getPositionForNewDashCard } from "metabase/lib/dashboard_grid";
@@ -25,6 +25,7 @@ import { push } from "react-router-redux";
 import { DashboardApi, CardApi, RevisionApi, PublicApi, EmbedApi } from "metabase/services";
 
 import { getDashboard, getDashboardComplete } from "./selectors";
+import {getCardAfterVisualizationClick} from "metabase/visualizations/lib/utils";
 
 const DATASET_SLOW_TIMEOUT = 15 * 1000;
 
@@ -491,24 +492,43 @@ export const deletePublicLink = createAction(DELETE_PUBLIC_LINK, async ({ id })
     return { id };
 });
 
-/** All navigation actions from dashboards to cards (e.x. clicking a title, drill through)
- *  should go through this action, which merges any currently applied dashboard filters
- *  into the new card / URL parameters.
+/**
+ * All navigation actions from dashboards to cards (e.x. clicking a title, drill through)
+ * should go through this action, which merges any currently applied dashboard filters
+ * into the new card / URL parameters.
+ *
+ * User-triggered events that are handled here:
+ *     - clicking a dashcard legend:
+ *         * question title legend (only for single-question cards)
+ *         * series legend (multi-aggregation, multi-breakout, multiple questions)
+ *     - clicking the visualization inside dashcard
+ *         * drill-through (single series, multi-aggregation, multi-breakout, multiple questions)
+ *         * (not in 0.24.2 yet: drag on line/area/bar visualization)
+ *     - those all can be applied without or with a dashboard filter
  */
 
-// TODO Atte Keinänen 5/2/17: This could be combined with `setCardAndRun` of query_builder/actions.js
-// Having two separate actions for very similar behavior was a source of initial confusion for me
 const NAVIGATE_TO_NEW_CARD = "metabase/dashboard/NAVIGATE_TO_NEW_CARD";
-export const navigateToNewCard = createThunkAction(NAVIGATE_TO_NEW_CARD, (card: UnsavedCard, dashcard: DashCard) =>
-    (dispatch, getState) => {
-        const { metadata } = getState();
-        const { dashboardId, dashboards, parameterValues } = getState().dashboard;
-        const dashboard = dashboards[dashboardId];
+export const navigateToNewCardFromDashboard = createThunkAction(
+    NAVIGATE_TO_NEW_CARD,
+    ({ nextCard, previousCard, dashcard }) =>
+        (dispatch, getState) => {
+            const {metadata} = getState();
+            const {dashboardId, dashboards, parameterValues} = getState().dashboard;
+            const dashboard = dashboards[dashboardId];
+            const cardIsDirty = !_.isEqual(previousCard.dataset_query, nextCard.dataset_query);
+
+            const url = questionUrlWithParameters(
+                getCardAfterVisualizationClick(nextCard, previousCard),
+                metadata,
+                dashboard.parameters,
+                parameterValues,
+                dashcard && dashcard.parameter_mappings,
+                cardIsDirty
+            );
 
-        // $FlowFixMe
-        const url = questionUrlWithParameters(card, metadata, dashboard.parameters, parameterValues, dashcard && dashcard.parameter_mappings);
-        dispatch(push(url));
-    });
+            dispatch(push(url));
+        }
+);
 
 // reducers
 
diff --git a/frontend/src/metabase/meta/Card.js b/frontend/src/metabase/meta/Card.js
index ca2bc5d82cb5a536716ab632b543452689bbdb03..6db71543c4a7ca406d39036225f722aa2c660dde 100644
--- a/frontend/src/metabase/meta/Card.js
+++ b/frontend/src/metabase/meta/Card.js
@@ -131,7 +131,11 @@ export function applyParameters(
             continue;
         }
 
-        const mapping = _.findWhere(parameterMappings, { card_id: card.id, parameter_id: parameter.id });
+        const mapping = _.findWhere(parameterMappings, {
+            // $FlowFixMe original_card_id not included in the flow type of card
+            card_id: card.id || card.original_card_id,
+            parameter_id: parameter.id
+        });
         if (mapping) {
             // mapped target, e.x. on a dashboard
             datasetQuery.parameters.push({
@@ -158,7 +162,8 @@ export function questionUrlWithParameters(
     metadata: Metadata,
     parameters: Parameter[],
     parameterValues: ParameterValues = {},
-    parameterMappings: ParameterMapping[] = []
+    parameterMappings: ParameterMapping[] = [],
+    cardIsDirty: boolean = true
 ): DatasetQuery {
     if (!card.dataset_query) {
         return Urls.question(card.id);
@@ -174,6 +179,11 @@ export function questionUrlWithParameters(
         parameterMappings
     );
 
+    // If we have a clean question without parameters applied, don't add the dataset query hash
+    if (!cardIsDirty && datasetQuery.parameters && datasetQuery.parameters.length === 0) {
+        return Urls.question(card.id);
+    }
+
     const query = {};
     for (const datasetParameter of datasetQuery.parameters || []) {
         const cardParameter = _.find(cardParameters, p =>
diff --git a/frontend/src/metabase/meta/Card.spec.js b/frontend/src/metabase/meta/Card.spec.js
index 8830d733ab259bb4bdc9441ec8ee4124670040ed..f94eef948e3822f26ec664669b05071d275f8e4f 100644
--- a/frontend/src/metabase/meta/Card.spec.js
+++ b/frontend/src/metabase/meta/Card.spec.js
@@ -135,6 +135,26 @@ describe("metabase/meta/Card", () => {
                     )
                 });
             });
+            it("should return question URL even if only original_card_id is present", () => {
+                const cardWithOnlyOriginalCardId = { ...card, id: undefined, original_card_id: card.id };
+
+                const url = Card.questionUrlWithParameters(
+                    cardWithOnlyOriginalCardId,
+                    metadata,
+                    parameters,
+                    { "1": "bar" },
+                    parameterMappings
+                );
+                expect(parseUrl(url)).toEqual({
+                    pathname: "/question",
+                    query: {},
+                    card: assocIn(
+                        cardWithOnlyOriginalCardId,
+                        ["dataset_query", "query", "filter"],
+                        ["AND", ["=", ["field-id", 1], "bar"]]
+                    )
+                });
+            });
             it("should return question URL with number MBQL filter added", () => {
                 const url = Card.questionUrlWithParameters(
                     card,
diff --git a/frontend/src/metabase/meta/types/Visualization.js b/frontend/src/metabase/meta/types/Visualization.js
index e172b2037c269d320e2fa536e560514346cb0744..bc5b2132e500b6e8e182f167d87913e4e5317d51 100644
--- a/frontend/src/metabase/meta/types/Visualization.js
+++ b/frontend/src/metabase/meta/types/Visualization.js
@@ -53,7 +53,7 @@ export type ClickActionProps = {
 }
 
 export type ClickActionPopoverProps = {
-    onChangeCardAndRun: (card: ?Card) => void,
+    onChangeCardAndRun: (Object) => void,
     onClose: () => void,
 }
 
@@ -83,7 +83,7 @@ export type VisualizationProps = {
     onHoverChange: (?HoverObject) => void,
     onVisualizationClick: (?ClickObject) => void,
     visualizationIsClickable: (?ClickObject) => boolean,
-    onChangeCardAndRun: (card: Card) => void,
+    onChangeCardAndRun: (Object) => void,
 
     onUpdateVisualizationSettings: ({ [key: string]: any }) => void
 }
diff --git a/frontend/src/metabase/qb/components/actions/PivotByAction.jsx b/frontend/src/metabase/qb/components/actions/PivotByAction.jsx
index a26f75a88c74bcb73115d693338025dbe63f935f..c52cddaddc5e101b9b02e9c1859d496d4812c5e7 100644
--- a/frontend/src/metabase/qb/components/actions/PivotByAction.jsx
+++ b/frontend/src/metabase/qb/components/actions/PivotByAction.jsx
@@ -88,9 +88,14 @@ export default (name: string, icon: string, fieldFilter: FieldFilter) =>
                         fieldOptions={fieldOptions}
                         customFieldOptions={customFieldOptions}
                         onCommitBreakout={breakout => {
-                            onChangeCardAndRun(
-                                pivot(card, breakout, tableMetadata, dimensions)
-                            );
+                            onChangeCardAndRun({
+                                nextCard: pivot(
+                                    card,
+                                    breakout,
+                                    tableMetadata,
+                                    dimensions
+                                )
+                            });
                         }}
                         onClose={onClose}
                     />
diff --git a/frontend/src/metabase/qb/components/actions/SummarizeBySegmentMetricAction.jsx b/frontend/src/metabase/qb/components/actions/SummarizeBySegmentMetricAction.jsx
index 851400885e1aa61b750b3a204911d6c1c8afa231..94242389f2afeee09121e3b649f4823841bf8c33 100644
--- a/frontend/src/metabase/qb/components/actions/SummarizeBySegmentMetricAction.jsx
+++ b/frontend/src/metabase/qb/components/actions/SummarizeBySegmentMetricAction.jsx
@@ -34,9 +34,13 @@ export default ({ card, tableMetadata }: ClickActionProps): ClickAction[] => {
                     customFields={Query.getExpressions(query)}
                     availableAggregations={tableMetadata.aggregation_options}
                     onCommitAggregation={aggregation => {
-                        onChangeCardAndRun(
-                            summarize(card, aggregation, tableMetadata)
-                        );
+                        onChangeCardAndRun({
+                            nextCard: summarize(
+                                card,
+                                aggregation,
+                                tableMetadata
+                            )
+                        });
                         onClose && onClose();
                     }}
                 />
diff --git a/frontend/src/metabase/qb/lib/actions.js b/frontend/src/metabase/qb/lib/actions.js
index a5c8ecd6210696f2091ec967f21006af6e179239..e3578fc6d8ac5b2bcab242efd9b3fd350cc7c1a1 100644
--- a/frontend/src/metabase/qb/lib/actions.js
+++ b/frontend/src/metabase/qb/lib/actions.js
@@ -19,6 +19,7 @@ export const toUnderlyingData = (card: CardObject): ?CardObject => {
     const newCard = startNewCard("query");
     newCard.dataset_query = card.dataset_query;
     newCard.display = "table";
+    newCard.original_card_id = card.id;
     return newCard;
 };
 
diff --git a/frontend/src/metabase/query_builder/actions.js b/frontend/src/metabase/query_builder/actions.js
index 009fe04415527402dfb205af9cbaf697ecf64fac..b02e64cbb780a4dca19a4294a40c84ebe63f35d2 100644
--- a/frontend/src/metabase/query_builder/actions.js
+++ b/frontend/src/metabase/query_builder/actions.js
@@ -29,6 +29,7 @@ import { MetabaseApi, CardApi, UserApi } from "metabase/services";
 
 import { parse as urlParse } from "url";
 import querystring from "querystring";
+import {getCardAfterVisualizationClick} from "metabase/visualizations/lib/utils";
 
 export const SET_CURRENT_STATE = "metabase/qb/SET_CURRENT_STATE"; const setCurrentState = createAction(SET_CURRENT_STATE);
 
@@ -491,9 +492,12 @@ export const reloadCard = createThunkAction(RELOAD_CARD, () => {
     };
 });
 
-// setCardAndRun
-// Used when navigating browser history, when drilling through in visualizations / action widget,
-// and when having the entity details view open and clicking its cells
+/**
+ * `setCardAndRun` is used when:
+ *     - navigating browser history
+ *     - clicking in the entity details view
+ *     - `navigateToNewCardInsideQB` is being called (see below)
+ */
 export const SET_CARD_AND_RUN = "metabase/qb/SET_CARD_AND_RUN";
 export const setCardAndRun = createThunkAction(SET_CARD_AND_RUN, (nextCard, shouldUpdateUrl = true) => {
     return async (dispatch, getState) => {
@@ -518,8 +522,31 @@ export const setCardAndRun = createThunkAction(SET_CARD_AND_RUN, (nextCard, shou
     };
 });
 
+/**
+ * User-triggered events that are handled with this action:
+ *     - clicking a legend:
+ *         * series legend (multi-aggregation, multi-breakout, multiple questions)
+ *     - clicking the visualization itself
+ *         * drill-through (single series, multi-aggregation, multi-breakout, multiple questions)
+ *         * (not in 0.24.2 yet: drag on line/area/bar visualization)
+ *     - clicking an action widget action
+ *
+ * All these events can be applied either for an unsaved question or a saved question.
+ */
+export const NAVIGATE_TO_NEW_CARD = "metabase/qb/NAVIGATE_TO_NEW_CARD";
+export const navigateToNewCardInsideQB = createThunkAction(NAVIGATE_TO_NEW_CARD, ({ nextCard, previousCard }) => {
+    return async (dispatch, getState) => {
+        const nextCardIsClean = _.isEqual(previousCard.dataset_query, nextCard.dataset_query) && previousCard.display === nextCard.display;
+
+        if (nextCardIsClean) {
+            // This is mainly a fallback for scenarios where a visualization legend is clicked inside QB
+            dispatch(setCardAndRun(await loadCard(nextCard.id)));
+        } else {
+            dispatch(setCardAndRun(getCardAfterVisualizationClick(nextCard, previousCard)));
+        }
+    }
+});
 
-// setDatasetQuery
 export const SET_DATASET_QUERY = "metabase/qb/SET_DATASET_QUERY";
 export const setDatasetQuery = createThunkAction(SET_DATASET_QUERY, (dataset_query, run = false) => {
     return (dispatch, getState) => {
diff --git a/frontend/src/metabase/query_builder/components/ActionsWidget.jsx b/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
index 981c66149e17f7b953854e00fd9d54ff83196ce8..eba3825141b79b5e1df080e34d80d6612c170acc 100644
--- a/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
@@ -12,7 +12,7 @@ import MetabaseAnalytics from "metabase/lib/analytics";
 import cx from "classnames";
 import _ from "underscore";
 
-import type { Card, UnsavedCard } from "metabase/meta/types/Card";
+import type { Card, UnsavedCard} from "metabase/meta/types/Card";
 import type { QueryMode, ClickAction } from "metabase/meta/types/Visualization";
 import type { TableMetadata } from "metabase/meta/types/Metadata";
 
@@ -21,7 +21,7 @@ type Props = {
     mode: QueryMode,
     card: Card,
     tableMetadata: TableMetadata,
-    setCardAndRun: (card: Card) => void
+    navigateToNewCardInsideQB: any => void
 };
 
 const CIRCLE_SIZE = 48;
@@ -71,18 +71,9 @@ export default class ActionsWidget extends Component<*, Props, *> {
         });
     };
 
-    handleOnChangeCardAndRun(nextCard: UnsavedCard|Card) {
-        const { card } = this.props;
-
-        // Include the original card id if present for showing the lineage next to title
-        const nextCardWithOriginalId = {
-            ...nextCard,
-            // $FlowFixMe
-            original_card_id: card.id || card.original_card_id
-        };
-        if (nextCardWithOriginalId) {
-            this.props.setCardAndRun(nextCardWithOriginalId);
-        }
+    handleOnChangeCardAndRun = ({ nextCard }: { nextCard: Card|UnsavedCard}) => {
+        const { card: previousCard } = this.props;
+        this.props.navigateToNewCardInsideQB({ nextCard, previousCard });
     }
 
     handleActionClick = (index: number) => {
@@ -94,7 +85,7 @@ export default class ActionsWidget extends Component<*, Props, *> {
             const nextCard = action.card();
             if (nextCard) {
                 MetabaseAnalytics.trackEvent("Actions", "Executed Action", `${action.section||""}:${action.name||""}`);
-                this.handleOnChangeCardAndRun(nextCard);
+                this.handleOnChangeCardAndRun({ nextCard });
             }
             this.close();
         }
@@ -170,12 +161,12 @@ export default class ActionsWidget extends Component<*, Props, *> {
                                           </div>
                                       </div>
                                       <PopoverComponent
-                                          onChangeCardAndRun={(card) => {
-                                              if (card) {
+                                          onChangeCardAndRun={({ nextCard }) => {
+                                              if (nextCard) {
                                                   if (selectedAction) {
                                                       MetabaseAnalytics.trackEvent("Actions", "Executed Action", `${selectedAction.section||""}:${selectedAction.name||""}`);
                                                   }
-                                                  this.handleOnChangeCardAndRun(card)
+                                                  this.handleOnChangeCardAndRun({ nextCard })
                                               }
                                           }}
                                           onClose={this.close}
diff --git a/frontend/src/metabase/query_builder/components/VisualizationResult.jsx b/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
index d959a936de3aa3bd747248fb0e3213abc5c18bb3..def5c8c63df9aadc09776c1812e99a8390de311c 100644
--- a/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
+++ b/frontend/src/metabase/query_builder/components/VisualizationResult.jsx
@@ -7,7 +7,7 @@ import VisualizationErrorMessage from './VisualizationErrorMessage';
 import Visualization from "metabase/visualizations/components/Visualization.jsx";
 import { datasetContainsNoResults } from "metabase/lib/dataset";
 
-const VisualizationResult = ({card, isObjectDetail, lastRunDatasetQuery, result, ...props}) => {
+const VisualizationResult = ({card, isObjectDetail, lastRunDatasetQuery, navigateToNewCardInsideQB, result, ...props}) => {
     const noResults = datasetContainsNoResults(result.data);
 
     if (isObjectDetail) {
@@ -34,7 +34,7 @@ const VisualizationResult = ({card, isObjectDetail, lastRunDatasetQuery, result,
         };
         return <Visualization
                   series={[{ card: vizCard, data: result.data }]}
-                  onChangeCardAndRun={props.setCardAndRun}
+                  onChangeCardAndRun={navigateToNewCardInsideQB}
                   isEditing={true}
                   // Table:
                   {...props}
@@ -43,11 +43,11 @@ const VisualizationResult = ({card, isObjectDetail, lastRunDatasetQuery, result,
 }
 
 VisualizationResult.propTypes = {
-    card:                   PropTypes.object.isRequired,
-    isObjectDetail:         PropTypes.bool.isRequired,
-    lastRunDatasetQuery:    PropTypes.object.isRequired,
-    result:                 PropTypes.object.isRequired,
-    setCardAndRun:          PropTypes.func,
+    card:                     PropTypes.object.isRequired,
+    isObjectDetail:           PropTypes.bool.isRequired,
+    lastRunDatasetQuery:      PropTypes.object.isRequired,
+    result:                   PropTypes.object.isRequired,
+    navigateToNewCardInsideQB:  PropTypes.func,
 }
 
 export default VisualizationResult;
diff --git a/frontend/src/metabase/visualizations/components/ChartClickActions.jsx b/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
index 13182daf6a5ece303c9310479606c5a9592959e6..e2065002f6913ac87c419d10c3a1505e2077a9df 100644
--- a/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
+++ b/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
@@ -9,7 +9,6 @@ import Popover from "metabase/components/Popover";
 import MetabaseAnalytics from "metabase/lib/analytics";
 
 import type { ClickObject, ClickAction } from "metabase/meta/types/Visualization";
-import type { Card } from "metabase/meta/types/Card";
 
 import _ from "underscore";
 
@@ -54,7 +53,7 @@ Object.values(SECTIONS).map((section, index) => {
 type Props = {
     clicked: ClickObject,
     clickActions: ?ClickAction[],
-    onChangeCardAndRun: (card: ?Card) => void,
+    onChangeCardAndRun: (Object) => void,
     onClose: () => void
 };
 
@@ -79,12 +78,12 @@ export default class ChartClickActions extends Component<*, Props, State> {
         if (action.popover) {
             this.setState({ popoverAction: action });
         } else if (action.card) {
-            const card = action.card();
+            const nextCard = action.card();
             MetabaseAnalytics.trackEvent("Actions", "Executed Click Action", `${action.section||""}:${action.name||""}`);
-            onChangeCardAndRun(card);
+            onChangeCardAndRun({ nextCard });
             this.close();
         }
-    }
+    };
 
     render() {
         const { clicked, clickActions, onChangeCardAndRun } = this.props;
@@ -99,11 +98,11 @@ export default class ChartClickActions extends Component<*, Props, State> {
             const PopoverContent = popoverAction.popover;
             popover = (
                 <PopoverContent
-                    onChangeCardAndRun={(card) => {
+                    onChangeCardAndRun={({ nextCard }) => {
                         if (popoverAction) {
                             MetabaseAnalytics.trackEvent("Action", "Executed Click Action", `${popoverAction.section||""}:${popoverAction.name||""}`);
                         }
-                        onChangeCardAndRun(card);
+                        onChangeCardAndRun({ nextCard });
                     }}
                     onClose={() => {
                         MetabaseAnalytics.trackEvent("Action", "Dismissed Click Action Menu");
diff --git a/frontend/src/metabase/visualizations/components/LegendHeader.jsx b/frontend/src/metabase/visualizations/components/LegendHeader.jsx
index bec9352dd3b06ea6fec5dbb6a499bbfbc9e63cc2..bd7aa4221770d9a310cb5375dfb44daec8fbdaff 100644
--- a/frontend/src/metabase/visualizations/components/LegendHeader.jsx
+++ b/frontend/src/metabase/visualizations/components/LegendHeader.jsx
@@ -71,7 +71,7 @@ export default class LegendHeader extends Component {
                         onClick={s.clicked && visualizationIsClickable(s.clicked) ?
                             ((e) => onVisualizationClick({ ...s.clicked, element: e.currentTarget }))
                         : onChangeCardAndRun ?
-                            ((e) => onChangeCardAndRun(s.card))
+                            (() => onChangeCardAndRun({ nextCard: s.card, seriesIndex: index }))
                         : null }
                     />,
                     onRemoveSeries && index > 0 &&
diff --git a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
index 17a6b75f3aa7260907b4b564b50b75d5ee7dd2f6..a30ae39db976c6efb3155c89650cdc3ab7f18844 100644
--- a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
+++ b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
@@ -188,11 +188,15 @@ export default class LineAreaBarChart extends Component<*, VisualizationProps, *
 
         let originalSeries = series._raw || series;
         let cardIds = _.uniq(originalSeries.map(s => s.card.id))
+        const isComposedOfMultipleQuestions = cardIds.length > 1;
 
         if (showTitle && settings["card.title"]) {
             titleHeaderSeries = [{ card: {
                 name: settings["card.title"],
-                id: cardIds.length === 1 ? cardIds[0] : null
+                ...(isComposedOfMultipleQuestions ? {} : {
+                    id: cardIds[0],
+                    dataset_query: originalSeries[0].card.dataset_query
+                }),
             }}];
         }
 
@@ -208,7 +212,9 @@ export default class LineAreaBarChart extends Component<*, VisualizationProps, *
                         series={titleHeaderSeries}
                         description={settings["card.description"]}
                         actionButtons={actionButtons}
-                        onChangeCardAndRun={onChangeCardAndRun}
+                        // If a dashboard card is composed of multiple questions, its custom card title
+                        // shouldn't act as a link as it's ambiguous that which question it should open
+                        onChangeCardAndRun={ isComposedOfMultipleQuestions ? null : onChangeCardAndRun }
                     />
                 : null }
                 { multiseriesHeaderSeries || (!titleHeaderSeries && actionButtons) ? // always show action buttons if we have them
diff --git a/frontend/src/metabase/visualizations/components/Visualization.jsx b/frontend/src/metabase/visualizations/components/Visualization.jsx
index c740ea684b457633a6dfa912e29a1abdc9985c49..c352b55afbad0fcaa97601c2ab4f60561f711bc7 100644
--- a/frontend/src/metabase/visualizations/components/Visualization.jsx
+++ b/frontend/src/metabase/visualizations/components/Visualization.jsx
@@ -31,7 +31,7 @@ import cx from "classnames";
 export const ERROR_MESSAGE_GENERIC = "There was a problem displaying this chart.";
 export const ERROR_MESSAGE_PERMISSION = "Sorry, you don't have permission to see this card."
 
-import type { UnsavedCard, VisualizationSettings} from "metabase/meta/types/Card";
+import type { VisualizationSettings} from "metabase/meta/types/Card";
 import type { HoverObject, ClickObject, Series } from "metabase/meta/types/Visualization";
 import type { Metadata } from "metabase/meta/types/Metadata";
 
@@ -63,7 +63,7 @@ type Props = {
 
     // for click actions
     metadata: Metadata,
-    onChangeCardAndRun: (card: UnsavedCard) => void,
+    onChangeCardAndRun: any => void,
 
     // used for showing content in place of visualization, e.x. dashcard filter mapping
     replacementContent: Element<any>,
@@ -221,27 +221,16 @@ export default class Visualization extends Component<*, Props, State> {
         setTimeout(() => {
             this.setState({ clicked });
         }, 100);
-    }
+    };
 
-    handleOnChangeCardAndRun = (card: UnsavedCard) => {
+    // Add the underlying card of current series to onChangeCardAndRun if available
+    handleOnChangeCardAndRun = ({ nextCard, seriesIndex }) => {
         const { series, clicked } = this.state;
 
-        const index = (clicked && clicked.seriesIndex) || 0;
-        const originalCard = series && series[index] && series[index].card;
+        const index = seriesIndex || (clicked && clicked.seriesIndex) || 0;
+        const previousCard = series && series[index] && series[index].card;
 
-        let cardId = card.id || card.original_card_id;
-        // if the supplied card doesn't have an id, get it from the original card
-        if (cardId == null && originalCard) {
-            // $FlowFixMe
-            cardId = originalCard.id || originalCard.original_card_id;
-        }
-
-        this.props.onChangeCardAndRun({
-            ...card,
-            id: cardId,
-            // $FlowFixMe
-            original_card_id: cardId
-        });
+        this.props.onChangeCardAndRun({ nextCard, previousCard });
     }
 
     onRender = ({ yAxisSplit, warnings = [] } = {}) => {
diff --git a/frontend/src/metabase/visualizations/lib/utils.js b/frontend/src/metabase/visualizations/lib/utils.js
index c776525135fcb9e7ac46f0d0841c7020bb82785c..5aa2aa826e3e930abb3b51c26fa759567b2889f3 100644
--- a/frontend/src/metabase/visualizations/lib/utils.js
+++ b/frontend/src/metabase/visualizations/lib/utils.js
@@ -249,3 +249,32 @@ function wrapMethod(object, name, method) {
         }
     }
 }
+// TODO Atte Keinänen 5/30/17 Extract to metabase-lib card/question logic
+export const cardHasBecomeDirty = (nextCard, previousCard) =>
+    !_.isEqual(previousCard.dataset_query, nextCard.dataset_query) || previousCard.display !== nextCard.display;
+
+export function getCardAfterVisualizationClick(nextCard, previousCard) {
+    if (cardHasBecomeDirty(nextCard, previousCard)) {
+        const isMultiseriesQuestion = !nextCard.id;
+        const alreadyHadLineage = !!previousCard.original_card_id;
+
+        return {
+            ...nextCard,
+            // Original card id is needed for showing the "started from" lineage in dirty cards.
+            original_card_id: alreadyHadLineage
+                // Just recycle the original card id of previous card if there was one
+                ? previousCard.original_card_id
+                // A multi-aggregation or multi-breakout series legend / drill-through action
+                // should always use the id of underlying/previous card
+                : (isMultiseriesQuestion ? previousCard.id : nextCard.id)
+        }
+    } else {
+        // Even though the card is currently clean, we might still apply dashboard parameters to it,
+        // so add the original_card_id to ensure a correct behavior in that context
+        return {
+            ...nextCard,
+            original_card_id: nextCard.id
+        };
+    }
+}
+
diff --git a/frontend/src/metabase/visualizations/lib/utils.spec.js b/frontend/src/metabase/visualizations/lib/utils.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..4123abdd97ab53dc8c74e3356cea72ec1c1d4959
--- /dev/null
+++ b/frontend/src/metabase/visualizations/lib/utils.spec.js
@@ -0,0 +1,171 @@
+import {cardHasBecomeDirty, getCardAfterVisualizationClick} from "./utils";
+import _ from "underscore";
+
+// TODO Atte Keinänen 5/31/17 Rewrite tests using metabase-lib methods instead of a raw format
+
+const baseQuery = {
+    "database": 1,
+    "type": "query",
+    "query": {
+        "source_table": 2,
+        "aggregation": [
+            [
+                "count"
+            ]
+        ],
+        "breakout": [
+            [
+                "field-id",
+                2
+            ]
+        ]
+    }
+};
+const derivedQuery = {
+    ...baseQuery,
+    "query": {
+        ...baseQuery.query,
+        "filter": [
+            "time-interval",
+            [
+                "field-id",
+                1
+            ],
+            -7,
+            "day"
+        ]
+    }
+};
+
+const breakoutMultiseriesQuery = {
+    ...baseQuery,
+    "query": {
+        ...baseQuery.query,
+        "breakout": [
+            ...baseQuery.query.breakout,
+            [
+                "fk->",
+                1,
+                10
+            ]
+        ]
+    }
+};
+const derivedBreakoutMultiseriesQuery = {
+    ...breakoutMultiseriesQuery,
+    "query": {
+        ...breakoutMultiseriesQuery.query,
+        "filter": [
+            "time-interval",
+            [
+                "field-id",
+                1
+            ],
+            -7,
+            "day"
+        ]
+    }
+};
+
+const savedCard = {
+    id: 3,
+    dataset_query: baseQuery,
+    display: "line"
+};
+const clonedSavedCard = {
+    id: 3,
+    dataset_query: _.clone(baseQuery),
+    display: "line"
+};
+const dirtyCardOnlyOriginalId = {
+    original_card_id: 7,
+    dataset_query: baseQuery,
+    display: "line"
+};
+
+const derivedCard = {
+    ...dirtyCardOnlyOriginalId,
+    dataset_query: derivedQuery
+};
+const derivedCardModifiedId = {
+    ...savedCard,
+    dataset_query: derivedQuery
+};
+const derivedDirtyCard = {
+    ...dirtyCardOnlyOriginalId,
+    dataset_query: derivedQuery
+};
+
+const derivedCardWithDifferentDisplay = {
+    ...savedCard,
+    display: "table"
+};
+
+const savedMultiseriesCard = {
+    ...savedCard,
+    dataset_query: breakoutMultiseriesQuery
+};
+const derivedMultiseriesCard = {
+    // id is not present when drilling through series / multiseries
+    dataset_query: derivedBreakoutMultiseriesQuery,
+    display: savedCard.display
+};
+const newCard = {
+    dataset_query: baseQuery,
+    display: "line"
+};
+const modifiedNewCard = {
+    dataset_query: derivedQuery,
+    display: "line"
+};
+
+describe("metabase/visualization/lib/utils", () => {
+    describe("cardHasBecomeDirty", () => {
+        it("should consider cards with different display types dirty", () => {
+            // mostly for action widget actions that only change the display type
+            expect(cardHasBecomeDirty(derivedCardWithDifferentDisplay, savedCard)).toEqual(true);
+        });
+
+        it("should consider cards with different data data dirty", () => {
+            expect(cardHasBecomeDirty(derivedCard, savedCard)).toEqual(true);
+        });
+
+        it("should consider cards with same display type and data clean", () => {
+            // i.e. the card is practically the same as original card
+            expect(cardHasBecomeDirty(clonedSavedCard, savedCard)).toEqual(false);
+        });
+    });
+
+    describe("getCardAfterVisualizationClick", () => {
+        it("should use the id of a previous card in case of a multi-breakout visualization", () => {
+            expect(getCardAfterVisualizationClick(derivedMultiseriesCard, savedMultiseriesCard))
+                .toMatchObject({original_card_id: savedMultiseriesCard.id})
+        });
+
+        // TODO: Atte Keinänen 5/31/17 This scenario is a little fuzzy at the moment as there have been
+        // some specific corner cases where the id in previousCard is wrong/missing
+        // We should validate that previousCard always has an id as it should
+        it("if the new card contains the id it's more reliable to use it for initializing lineage", () => {
+            expect(getCardAfterVisualizationClick(derivedCardModifiedId, savedCard))
+                .toMatchObject({original_card_id: derivedCardModifiedId.id})
+        });
+
+        it("should be able to continue the lineage even if the previous question was dirty already", () => {
+            expect(getCardAfterVisualizationClick(derivedDirtyCard, dirtyCardOnlyOriginalId))
+                .toMatchObject({original_card_id: dirtyCardOnlyOriginalId.original_card_id})
+        });
+
+        it("should just pass the new question if the previous question was new", () => {
+            expect(getCardAfterVisualizationClick(modifiedNewCard, newCard))
+                .toMatchObject(modifiedNewCard)
+        });
+
+        it("should populate original_card_id even if the question isn't modified", () => {
+            // This is the hack to interoperate with questionUrlWithParameters when
+            // dashboard parameters are applied to a dashcards
+            expect(getCardAfterVisualizationClick(clonedSavedCard, savedCard))
+                .toMatchObject({original_card_id: savedCard.id})
+        });
+    })
+});
+
diff --git a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
index a973509d374442caa81a4fb5942033d0378b5d20..730f9b614a93ac56b148a10d331bea4b7ce89e77 100644
--- a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
@@ -194,7 +194,7 @@ export default class Scalar extends Component<*, VisualizationProps, *> {
                 <div className={styles.Title + " flex align-center"}>
                     <Ellipsified tooltip={card.name}>
                         <span
-                            onClick={onChangeCardAndRun && (() => onChangeCardAndRun(card))}
+                            onClick={onChangeCardAndRun && (() => onChangeCardAndRun({ nextCard: card }))}
                             className={cx("fullscreen-normal-text fullscreen-night-text", {
                                 "cursor-pointer": !!onChangeCardAndRun
                             })}