From 5b78105212677c4c6f07d60a94296f7719ec7807 Mon Sep 17 00:00:00 2001 From: Xavier Fernandes Date: Wed, 26 May 2021 10:41:39 -0700 Subject: [PATCH] Sorting and filtering with descending by default --- README.md | 2 +- frontend/MainContainer.tsx | 3 +- .../components/PerspectiveScoresBarChart.tsx | 40 ++++++-- frontend/components/TextGenerationControl.tsx | 26 ++--- frontend/components/TextGenerationResults.tsx | 94 ++++++++++++++----- transformerviz/helpers/utils.py | 83 ++++++++++++++-- transformerviz/server.py | 13 ++- 7 files changed, 206 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 54d6130..1c9cd73 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,6 @@ Any use of third-party trademarks or logos are subject to those third-party's po ## Running -- `PERSPECTIVE_API_KEY= TRANSFORMERS_CACHE= FLASK_APP=transformerviz/server.py flask run --host 0.0.0.0 --port 5000` (The `TRANSFORMERS_CACHE` environment variable is optional). +- `PERSPECTIVE_API_KEY= GPT2_MODEL_VERSION= NUM_RETURN_SEQUENCES= TRANSFORMERS_CACHE= FLASK_APP=transformerviz/server.py flask run --host 0.0.0.0 --port 5000` (The `TRANSFORMERS_CACHE` environment variable is optional). - Point your browser to port 5000 of the server on which the app is running. diff --git a/frontend/MainContainer.tsx b/frontend/MainContainer.tsx index 5f5b466..c729e0d 100644 --- a/frontend/MainContainer.tsx +++ b/frontend/MainContainer.tsx @@ -69,7 +69,8 @@ const Container: React.FunctionComponent = ({ loading={loading} error={error} onSelectTextId={selectText} - selectedTextIds={selectedTextIds} /> + selectedTextIds={selectedTextIds} + /> {getDetailedAnalysisComponent()} diff --git a/frontend/components/PerspectiveScoresBarChart.tsx b/frontend/components/PerspectiveScoresBarChart.tsx index 1eadd10..b31350a 100644 --- a/frontend/components/PerspectiveScoresBarChart.tsx +++ b/frontend/components/PerspectiveScoresBarChart.tsx @@ -3,6 +3,7 @@ import ReactDOM from "react-dom"; import * as d3 from "d3"; import { DirectionalHint } from 'office-ui-fabric-react/lib/Tooltip'; import { PrimaryButton, DefaultButton } from 'office-ui-fabric-react/lib/Button'; +import AnalyzedText from "../models/AnalyzedText"; type PerspectiveScoresBarChartState = { @@ -12,8 +13,8 @@ type PerspectiveScoresBarChartState = { type PerspectiveScoresBarChartProps = { id: number, width: number, - scores: any, - defaultSelectedScore: string + defaultSelectedScore: string, + analyzedText: AnalyzedText } class PerspectiveScoresBarChart extends Component { @@ -41,6 +42,12 @@ class PerspectiveScoresBarChart extends Component { this.setState({ selectedScore: selectedScore @@ -51,6 +58,23 @@ class PerspectiveScoresBarChart extends Component { + let resultScores = [ + {label: "toxicity", value: item.toxicity, scoreName: "Toxicity"}, + {label: "severeToxicity", value: item.severeToxicity, scoreName: "Severe Toxicity"}, + {label: "identityAttack", value: item.identityAttack, scoreName: "Identity Attack"}, + {label: "insult", value: item.insult, scoreName: "Insult"}, + {label: "profanity", value: item.profanity, scoreName: "Profanity"}, + {label: "threat", value: item.threat, scoreName: "Threat"}, + {label: "sexuallyExplicit", value: item.sexuallyExplicit, scoreName: "Sexually Explicit"}, + {label: "flirtation", value: item.flirtation, scoreName: "Flirtation"} + ]; + + return resultScores; + } + + var scores = getResultScoreObj(this.props.analyzedText); + var margin = { top: 5, right: 15, bottom: 50, left: 55 } var h = 111 - margin.top - margin.bottom var w = this.props.width; @@ -69,10 +93,10 @@ class PerspectiveScoresBarChart extends Component (scoreObj.score == this.state.selectedScore))[0]; + var selectedScoreObj = scores.filter(scoreObj => (scoreObj.label == this.state.selectedScore))[0]; var selectedScoreMessage = `${selectedScoreObj.scoreName}: ${selectedScoreObj.value.toFixed(2)}`; g.append("g") @@ -86,16 +110,16 @@ class PerspectiveScoresBarChart extends Component { - this.props.generateText({ - prompt: this.state.textGenerationPrompt, - model: this.state.model, - do_sample: this.state.doSample, - early_stopping: this.state.earlyStopping, - min_length: this.state.minLength, - max_length: this.state.maxLength, - top_k: this.state.topK, - top_p: this.state.topP, - temperature: this.state.temperature, - num_beams: this.state.numBeams, - }); + if (this.state.textGenerationPrompt.trim().length != 0) { + this.props.generateText({ + prompt: this.state.textGenerationPrompt, + model: this.state.model, + do_sample: this.state.doSample, + early_stopping: this.state.earlyStopping, + min_length: this.state.minLength, + max_length: this.state.maxLength, + top_k: this.state.topK, + top_p: this.state.topP, + temperature: this.state.temperature, + num_beams: this.state.numBeams, + }); + } }; onTextPromptChange = (evt) => { diff --git a/frontend/components/TextGenerationResults.tsx b/frontend/components/TextGenerationResults.tsx index 4cc0812..f1f5d0d 100644 --- a/frontend/components/TextGenerationResults.tsx +++ b/frontend/components/TextGenerationResults.tsx @@ -11,13 +11,66 @@ type TextGenerationResultsProps = { error?: any } -class TextGenerationResults extends React.Component { +type TextGenerationResultsState = { + analysisResults: AnalyzedText[], + highlightScoreLabel: string, + sortByLabel: string +} + +class TextGenerationResults extends React.Component { constructor(props) { super(props); + + this.state = { + analysisResults: props.analysisResults, + highlightScoreLabel: "toxicity", + sortByLabel: "none" + } + } + + componentWillReceiveProps(nextProps) { + this.setState({ + analysisResults: nextProps.analysisResults + }); + } + + sortGeneratedTextResults(scoreLabel) { + if (scoreLabel == "none") { + this.setState({ + sortByLabel: scoreLabel, + analysisResults: this.props.analysisResults + }); + } else { + const sortedAnalysisResults = this.state.analysisResults.map((result) => result).sort((resultA, resultB) => { + if (resultA[scoreLabel] < resultB[scoreLabel]) { + return -1; + } else if (resultA[scoreLabel] == resultB[scoreLabel]) { + return 0; + } else { + return 1; + } + }); + + this.setState({ + sortByLabel: scoreLabel, + analysisResults: sortedAnalysisResults + }); + } + } + + setHighlightedScoreLabel(scoreLabel) { + if (scoreLabel != this.state.highlightScoreLabel) { + this.setState({ + analysisResults: this.props.analysisResults, + highlightScoreLabel: scoreLabel, + sortByLabel: "none" + }); + } } render() { + console.log(this.state); if (this.props.error != null) { return ( @@ -34,41 +87,26 @@ class TextGenerationResults extends React.Component { - let resultScores = [ - {score: "TOXICITY", value: item.toxicity, scoreName: "Toxicity"}, - {score: "SEVERE_TOXICITY", value: item.severeToxicity, scoreName: "Severe Toxicity"}, - {score: "IDENTITY_ATTACK", value: item.identityAttack, scoreName: "Identity Attack"}, - {score: "INSULT", value: item.insult, scoreName: "Insult"}, - {score: "PROFANITY", value: item.profanity, scoreName: "Profanity"}, - {score: "THREAT", value: item.threat, scoreName: "Threat"}, - {score: "SEXUALLY_EXPLICIT", value: item.sexuallyExplicit, scoreName: "Sexually Explicit"}, - {score: "FLIRTATION", value: item.flirtation, scoreName: "Flirtation"} - ]; - - return resultScores; - } - const sortOptions: IComboBoxOption[] = [ + { key: 'none', text: 'None'}, { key: 'toxicity', text: 'Toxicity' }, - { key: 'severe', text: 'Severe Toxicity' }, + { key: 'severeToxicity', text: 'Severe Toxicity' }, { key: 'identity', text: 'Identity Attack' }, { key: 'insult', text: 'Insult' }, { key: 'profanity', text: 'Profanity' }, { key: 'threat', text: 'Threat' }, - { key: 'sexually', text: 'Sexually Explicit' }, + { key: 'sexuallyExplicit', text: 'Sexually Explicit' }, { key: 'flirtation', text: 'Flirtation' }, ]; const scoreOptions: IComboBoxOption[] = [ - { key: 'all', text: 'All Scores' }, { key: 'toxicity', text: 'Toxicity' }, - { key: 'severe', text: 'Severe Toxicity' }, - { key: 'identity', text: 'Identity Attack' }, + { key: 'severeToxicity', text: 'Severe Toxicity' }, + { key: 'identityAttack', text: 'Identity Attack' }, { key: 'insult', text: 'Insult' }, { key: 'profanity', text: 'Profanity' }, { key: 'threat', text: 'Threat' }, - { key: 'sexually', text: 'Sexually Explicit' }, + { key: 'sexuallyExplicit', text: 'Sexually Explicit' }, { key: 'flirtation', text: 'Flirtation' }, ]; @@ -83,20 +121,28 @@ class TextGenerationResults extends React.Component { + this.sortGeneratedTextResults(option.key); + }} /> { + this.setHighlightedScoreLabel(option.key); + }} /> - {this.props.analysisResults.map((item) => + {this.state.analysisResults.map((item) =>
{item.id}
- +