tweak: Further question page changes
- Add estimate of likeliest option to top - Or of event happening for yes/no questions - Restore selection highlight from legend - But avoid weird color errors - Add a bunch of parameters to QuestionOptions - I could just have added a flag for isInQuestionPage, - Not sure if this is the best way to go about this I'm not particularly planning to continue with changes in the upcoming days
This commit is contained in:
parent
7236e9662f
commit
020f0c0c5e
|
@ -36,8 +36,8 @@ const getVictoryGroup = ({
|
||||||
style={{
|
style={{
|
||||||
data: {
|
data: {
|
||||||
// strokeOpacity: highlight ? 1 : 0.5,
|
// strokeOpacity: highlight ? 1 : 0.5,
|
||||||
strokeOpacity: 0.6,
|
strokeOpacity: highlight && !isBinary ? 0.8 : 0.6,
|
||||||
strokeWidth: 3,
|
strokeWidth: highlight && !isBinary ? 4 : 3,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -116,14 +116,24 @@ export const QuestionCard: React.FC<Props> = ({
|
||||||
</div>
|
</div>
|
||||||
{isBinary ? (
|
{isBinary ? (
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<QuestionOptions question={question} />
|
<QuestionOptions
|
||||||
|
question={question}
|
||||||
|
maxNumOptions={5}
|
||||||
|
optionTextSize={"text-normal"}
|
||||||
|
onlyFirstEstimate={false}
|
||||||
|
/>
|
||||||
<div className={`hidden ${showTimeStamp ? "sm:block" : ""}`}>
|
<div className={`hidden ${showTimeStamp ? "sm:block" : ""}`}>
|
||||||
<LastUpdated timestamp={lastUpdated} />
|
<LastUpdated timestamp={lastUpdated} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<QuestionOptions question={question} />
|
<QuestionOptions
|
||||||
|
question={question}
|
||||||
|
maxNumOptions={5}
|
||||||
|
optionTextSize={"text-sm"}
|
||||||
|
onlyFirstEstimate={false}
|
||||||
|
/>
|
||||||
<div className={`hidden ${showTimeStamp ? "sm:block" : ""} ml-6`}>
|
<div className={`hidden ${showTimeStamp ? "sm:block" : ""} ml-6`}>
|
||||||
<LastUpdated timestamp={lastUpdated} />
|
<LastUpdated timestamp={lastUpdated} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
import { FullQuestionOption, isFullQuestionOption } from "../../../common/types";
|
import {
|
||||||
|
FullQuestionOption,
|
||||||
|
isFullQuestionOption,
|
||||||
|
} from "../../../common/types";
|
||||||
import { QuestionFragment } from "../../fragments.generated";
|
import { QuestionFragment } from "../../fragments.generated";
|
||||||
import { isQuestionBinary } from "../../utils";
|
import { isQuestionBinary } from "../../utils";
|
||||||
import { formatProbability } from "../utils";
|
import { formatProbability } from "../utils";
|
||||||
|
@ -89,26 +92,38 @@ const chooseColor = (probability: number) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const OptionRow: React.FC<{ option: FullQuestionOption }> = ({ option }) => {
|
const OptionRow: React.FC<{
|
||||||
|
option: FullQuestionOption;
|
||||||
|
optionTextSize: string;
|
||||||
|
}> = ({ option, optionTextSize }) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div
|
<div
|
||||||
className={`${chooseColor(
|
className={`${chooseColor(
|
||||||
option.probability
|
option.probability
|
||||||
)} w-14 flex-none rounded-md py-0.5 text-sm text-center`}
|
)} w-14 flex-none rounded-md py-0.5 ${
|
||||||
|
optionTextSize || "text-sm"
|
||||||
|
} text-center`}
|
||||||
>
|
>
|
||||||
{formatProbability(option.probability)}
|
{formatProbability(option.probability)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-gray-700 pl-3 leading-snug text-sm">
|
<div
|
||||||
|
className={`text-gray-700 pl-3 leading-snug ${
|
||||||
|
optionTextSize || "text-sm"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
{option.name}
|
{option.name}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const QuestionOptions: React.FC<{ question: QuestionFragment }> = ({
|
export const QuestionOptions: React.FC<{
|
||||||
question,
|
question: QuestionFragment;
|
||||||
}) => {
|
maxNumOptions: number;
|
||||||
|
optionTextSize: string;
|
||||||
|
onlyFirstEstimate: boolean;
|
||||||
|
}> = ({ question, maxNumOptions, optionTextSize, onlyFirstEstimate }) => {
|
||||||
const isBinary = isQuestionBinary(question);
|
const isBinary = isQuestionBinary(question);
|
||||||
|
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
|
@ -124,30 +139,65 @@ export const QuestionOptions: React.FC<{ question: QuestionFragment }> = ({
|
||||||
<span
|
<span
|
||||||
className={`${primaryForecastColor(
|
className={`${primaryForecastColor(
|
||||||
yesOption.probability
|
yesOption.probability
|
||||||
)} text-white w-16 rounded-md px-1.5 py-0.5 font-bold`}
|
)} text-white w-16 rounded-md px-2 py-1 font-bold ${
|
||||||
|
optionTextSize || "text-normal"
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{formatProbability(yesOption.probability)}
|
{formatProbability(yesOption.probability)}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
className={`${textColor(
|
className={`${textColor(yesOption.probability)} ${
|
||||||
yesOption.probability
|
optionTextSize || "text-normal"
|
||||||
)} text-gray-500 inline-block`}
|
} text-gray-500 inline-block`}
|
||||||
>
|
>
|
||||||
{primaryEstimateAsText(yesOption.probability)}
|
{primaryEstimateAsText(yesOption.probability)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else if (onlyFirstEstimate) {
|
||||||
|
if (question.options.length > 0) {
|
||||||
|
const yesOption =
|
||||||
|
question.options.length > 0 ? question.options[0] : null;
|
||||||
|
if (!yesOption) {
|
||||||
|
return null; // shouldn't happen
|
||||||
|
}
|
||||||
|
if (!isFullQuestionOption(yesOption)) {
|
||||||
|
return null; // missing data
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="space-x-2">
|
||||||
|
<span
|
||||||
|
className={`${primaryForecastColor(
|
||||||
|
yesOption.probability
|
||||||
|
)} text-white w-16 rounded-md px-2 py-1 font-bold ${
|
||||||
|
optionTextSize || "text-normal"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{formatProbability(yesOption.probability)}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className={`${textColor(yesOption.probability)} ${
|
||||||
|
optionTextSize || "text-normal"
|
||||||
|
} text-gray-500 inline-block`}
|
||||||
|
>
|
||||||
|
{yesOption.name}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const optionsSorted = question.options
|
const optionsSorted = question.options
|
||||||
.filter(isFullQuestionOption)
|
.filter(isFullQuestionOption)
|
||||||
.sort((a, b) => b.probability - a.probability);
|
.sort((a, b) => b.probability - a.probability);
|
||||||
|
|
||||||
const optionsMax5 = optionsSorted.slice(0, 5); // display max 5 options.
|
const optionsMaxN = optionsSorted.slice(0, maxNumOptions); // display max 5 options.
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{optionsMax5.map((option, i) => (
|
{optionsMaxN.map((option, i) => (
|
||||||
<OptionRow option={option} key={i} />
|
<OptionRow option={option} key={i} optionTextSize={optionTextSize} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { CaptureQuestion } from "../components/CaptureQuestion";
|
||||||
import { HistoryChart } from "../components/HistoryChart";
|
import { HistoryChart } from "../components/HistoryChart";
|
||||||
import { IndicatorsTable } from "../components/IndicatorsTable";
|
import { IndicatorsTable } from "../components/IndicatorsTable";
|
||||||
import { Stars } from "../components/Stars";
|
import { Stars } from "../components/Stars";
|
||||||
|
import { QuestionOptions } from "../components/QuestionOptions";
|
||||||
import { QuestionPageDocument } from "../queries.generated";
|
import { QuestionPageDocument } from "../queries.generated";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -49,7 +50,15 @@ const Section: React.FC<{ title: string }> = ({ title, children }) => (
|
||||||
|
|
||||||
const LargeQuestionCard: React.FC<{
|
const LargeQuestionCard: React.FC<{
|
||||||
question: QuestionWithHistoryFragment;
|
question: QuestionWithHistoryFragment;
|
||||||
}> = ({ question }) => (
|
}> = ({ question }) => {
|
||||||
|
let probabilities = question.options;
|
||||||
|
let optionsOrderedByProbability = question.options.sort((a, b) =>
|
||||||
|
(a.probability || 0) > (b.probability || 0) ? -1 : 1
|
||||||
|
);
|
||||||
|
let optionWithHighestProbability =
|
||||||
|
question.options.length > 0 ? [optionsOrderedByProbability[0]] : [];
|
||||||
|
|
||||||
|
return (
|
||||||
<Card highlightOnHover={false} large={true}>
|
<Card highlightOnHover={false} large={true}>
|
||||||
<h1 className="sm:text-3xl text-xl">
|
<h1 className="sm:text-3xl text-xl">
|
||||||
<a
|
<a
|
||||||
|
@ -61,9 +70,9 @@ const LargeQuestionCard: React.FC<{
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div className="flex gap-2 mb-5">
|
<div className="flex gap-2 mb-5 mt-5">
|
||||||
<a
|
<a
|
||||||
className="text-black no-underline border-2 rounded-lg border-gray-400 rounded p-1 px-2 text-2xs hover:text-gray-600"
|
className="text-black no-underline border-2 rounded-lg border-gray-400 rounded p-1 px-2 text-normal hover:text-gray-600"
|
||||||
href={question.url}
|
href={question.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
@ -71,6 +80,14 @@ const LargeQuestionCard: React.FC<{
|
||||||
<FaExternalLinkAlt className="text-gray-400 inline sm:text-md text-md mb-1" />
|
<FaExternalLinkAlt className="text-gray-400 inline sm:text-md text-md mb-1" />
|
||||||
</a>
|
</a>
|
||||||
<Stars num={question.qualityIndicators.stars} />
|
<Stars num={question.qualityIndicators.stars} />
|
||||||
|
<span className="border-2 border-white p-1 px-2 ">
|
||||||
|
<QuestionOptions
|
||||||
|
question={{ ...question }}
|
||||||
|
maxNumOptions={1}
|
||||||
|
optionTextSize={"text-normal"}
|
||||||
|
onlyFirstEstimate={true}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-10">
|
<div className="mb-10">
|
||||||
|
@ -103,8 +120,8 @@ const LargeQuestionCard: React.FC<{
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
const QuestionScreen: React.FC<{ question: QuestionWithHistoryFragment }> = ({
|
const QuestionScreen: React.FC<{ question: QuestionWithHistoryFragment }> = ({
|
||||||
question,
|
question,
|
||||||
}) => (
|
}) => (
|
||||||
|
|
Loading…
Reference in New Issue
Block a user