Этот коммит содержится в:
higsch 2020-12-02 23:58:41 +01:00
родитель 06ef9c3806
Коммит d8d77a137a
7 изменённых файлов: 282 добавлений и 42 удалений

Просмотреть файл

@ -141,6 +141,36 @@ a:hover, span.pseudolink:hover {
background-color: #e24545a1;
}
/* polarization */
.pol-l {
background-color: #2e64a0;
opacity: 0.8;
}
.pol-ll {
background-color: #61a3de;
opacity: 0.8;
}
.pol-c {
background-color: #96659e;
opacity: 0.8;
}
.pol-lr {
background-color: #a15552;
opacity: 0.8;
}
.pol-r {
background-color: #ca0800;
opacity: 0.8;
}
.pol-undef {
background-color: #e0d3e2;
opacity: 0.8;
}
/* the landing page */
.page-wrapper {

Просмотреть файл

@ -4,7 +4,7 @@
import { width, panelHeight, controlsHeight } from '../stores/dimensions';
import { tooltip } from '../stores/eventSelections';
import { fade, slide } from 'svelte/transition';
import { timeFormat, format } from 'd3';
import { timeFormat } from 'd3';
import { extractHostname } from '../utils/misc';
import {
platformFilter,
@ -20,6 +20,8 @@
import EventTooltipCross from './EventTooltipCross.svelte';
import ScoreBar from './ScoreBar.svelte';
import ScoreQuestions from './ScoreQuestions.svelte';
import ImpactStrip from './ImpactStrip.svelte';
import PolarizationLegend from './PolarizationLegend.svelte';
import Share from './Share.svelte';
const offset = {
@ -32,7 +34,6 @@
const attributionTf = timeFormat('%B %d, %Y');
const activityTf = timeFormat('%B %Y');
const commaFormat = format(',');
let elem;
let tWidth, tHeight;
@ -181,19 +182,19 @@
<p>pending</p>
{:else}
<ul>
<li>
<span class="smi-score facebook">{commaFormat($tooltip.tp.smiFacebook)}</span>
<span class="smi-label">Facebook</span>
</li>
<li>
<span class="smi-score twitter">{commaFormat($tooltip.tp.smiTwitter)}</span>
<span class="smi-label">Twitter</span>
</li>
<li>
<span class="smi-score reddit">{commaFormat($tooltip.tp.smiReddit)}</span>
<span class="smi-label">Reddit</span>
</li>
<ImpactStrip value={$tooltip.tp.smiFacebook}
polarization={$tooltip.tp.polarization}
label="Facebook" />
<ImpactStrip value={$tooltip.tp.smiTwitter}
polarization={$tooltip.tp.polarization}
label="Twitter" />
<ImpactStrip value={$tooltip.tp.smiReddit}
polarization={$tooltip.tp.polarization}
label="Reddit" />
</ul>
{#if ($tooltip.tp.polarization.fulfills10Articles || $tooltip.tp.polarization.fulfills25Percent)}
<PolarizationLegend />
{/if}
{/if}
</div>
{#if ($tooltip.tp.imageUrl)}
@ -426,26 +427,6 @@
display: flex;
}
.smi li {
margin: 0.2rem 0.3rem 0.2rem 0;
font-size: 0.8rem;
}
.smi-score {
padding: 0 0.2rem;
border: none;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0,0,0,0.07),
0 2px 4px rgba(0,0,0,0.07);
}
.smi-label {
display: inline-block;
padding: 0 0.1rem;
border: none;
border-radius: 3px;
}
a {
text-decoration: none;
}
@ -458,11 +439,6 @@
font-size: 0.6rem;
}
.no-break {
word-break: keep-all;
white-space: nowrap;
}
.scroll-wrapper .image {
min-height: 1%;
width: 100%;

52
src/components/ImpactStrip.svelte Обычный файл
Просмотреть файл

@ -0,0 +1,52 @@
<script>
import { format } from 'd3';
import PolarizationStrip from './PolarizationStrip.svelte';
export let value = 0;
export let polarization;
export let label = '';
const commaFormat = format(',');
let valueWidth = 0;
</script>
<li>
<div class="smi-score {label.toLowerCase()}"
bind:clientWidth={valueWidth}>
{commaFormat(value)}
</div>
<span class="smi-label">
{label}
</span>
{#if ((polarization.fulfills10Articles || polarization.fulfills25Percent) && value > 0)}
<PolarizationStrip polarization={polarization[label.toLowerCase()]}
smi={value}
valueWidth={valueWidth} />
{/if}
</li>
<style>
li {
margin: 0.2rem 0.3rem 0.2rem 0;
font-size: 0.8rem;
min-width: 30%;
}
.smi-score {
display: inline-block;
padding: 0 0.2rem;
border: none;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07),
0 2px 4px rgba(0, 0, 0, 0.07);
}
.smi-label {
display: inline-block;
padding: 0 0.1rem;
border: none;
border-radius: 3px;
}
</style>

52
src/components/PolarizationLegend.svelte Обычный файл
Просмотреть файл

@ -0,0 +1,52 @@
<script>
import { categories } from '../inputs/polarization';
</script>
<div class="pol-legend">
<p>Polarization:</p>
<ul>
{#each categories as category (category)}
<li>
<div class="pol-legend-field pol-{category.id}"></div>
<p>{category.name}</p>
</li>
{/each}
</ul>
</div>
<style>
.pol-legend {
display: flex;
align-items: center;
font-family: var(--font-02);
color: var(--dfrlab-gray);
}
.pol-legend p {
margin-right: 0.7rem;
font-size: 0.7rem;
}
.pol-legend ul {
display: flex;
align-items: center;
height: 100%;
list-style-type: none;
}
.pol-legend ul li {
display: flex;
align-items: center;
height: 100%;
}
.pol-legend ul li p {
font-size: 0.6rem;
}
.pol-legend-field {
width: 0.5rem;
height: 0.5rem;
margin-right: 0.2rem;
}
</style>

108
src/components/PolarizationStrip.svelte Обычный файл
Просмотреть файл

@ -0,0 +1,108 @@
<script>
import { categories } from '../inputs/polarization';
import { scaleLinear, line as d3line, curveBasis } from 'd3';
export let polarization;
export let smi = 0;
export let valueWidth = 0;
const magnifierHeight = 20;
const margin = {
top: 4,
right: 2,
bottom: 0,
left: 2
};
const yScale = scaleLinear()
.domain([0, 1])
.range([margin.top, magnifierHeight - margin.bottom]);
const line = d3line()
.x((d) => d[0])
.y((d) => yScale(d[1]))
.curve(curveBasis);
let width;
let stack = {};
$: totalEngagement = Object.keys(polarization).map((k) => polarization[k]).reduce((acc, cur) => acc + cur);
$: engagementExplained = totalEngagement / smi;
$: Object.keys(polarization).forEach((k) => {
const value = polarization[k];
stack[k] = {
value,
width: Math.floor(100 * value / totalEngagement, 2)
};
});
$: leftPathData = [
[margin.left + valueWidth / 2 - engagementExplained * valueWidth / 2, 0],
[margin.left + valueWidth / 2 - engagementExplained * valueWidth / 2, 0.3],
[margin.left, 0.7],
[margin.left, 1]
];
$: rightPathData = [
[valueWidth / 2 + engagementExplained * valueWidth / 2 - margin.right, 0],
[valueWidth / 2 + engagementExplained * valueWidth / 2 - margin.right, 0.3],
[width * 0.98 - margin.right, 0.7],
[width * 0.98 - margin.right, 1]
];
</script>
<div class="polarization-strip"
bind:clientWidth={width}>
<svg class="pol-magnifier"
width={width}
height={magnifierHeight}>
<path d={line(leftPathData)} />
<path d={line(rightPathData)} />
<text x={valueWidth / 2}
y={yScale(1)}>
{Math.round(engagementExplained * 100)}%
</text>
</svg>
<div class="pol-layer-wrapper">
{#each categories as category (category.id)}
<div class="pol-layer pol-{category.id}"
style="width: {stack[category.id].width}%;">
</div>
{/each}
</div>
</div>
<style>
.polarization-strip {
width: 100%;
}
path {
stroke: var(--dfrlab-gray);
stroke-width: 1.5;
stroke-dasharray: 2 3;
stroke-linecap: round;
fill: none;
}
text {
font-family: var(--font-02);
font-size: 0.6rem;
text-anchor: middle;
fill: var(--dfrlab-gray);
}
.pol-layer-wrapper {
width: 100%;
height: 1rem;
border: none;
}
.pol-layer {
display: inline-block;
height: 100%;
}
</style>

22
src/inputs/polarization.js Обычный файл
Просмотреть файл

@ -0,0 +1,22 @@
export const categories = [
{
id: 'l',
name: 'left'
},
{
id: 'll',
name: 'leanleft'
},
{
id: 'c',
name: 'center'
},
{
id: 'lr',
name: 'leanright'
},
{
id: 'r',
name: 'right'
},
];

Просмотреть файл

@ -92,21 +92,21 @@ const loadData = async () => {
lr: +d.allsides_engagments_leanright,
r: +d.allsides_engagments_right
},
fb: {
facebook: {
l: +d.allsides_engagments_left_facebook,
ll: +d.allsides_engagments_leanleft_facebook,
c: +d.allsides_engagments_center_facebook,
lr: +d.allsides_engagments_leanright_facebook,
r: +d.allsides_engagments_right_facebook
},
tw: {
twitter: {
l: +d.allsides_engagments_left_twitter,
ll: +d.allsides_engagments_leanleft_twitter,
c: +d.allsides_engagments_center_twitter,
lr: +d.allsides_engagments_leanright_twitter,
r: +d.allsides_engagments_right_twitter
},
re: {
reddit: {
l: +d.allsides_engagments_left_reddit,
ll: +d.allsides_engagments_leanleft_reddit,
c: +d.allsides_engagments_center_reddit,