colored source links according to general polarization
Этот коммит содержится в:
родитель
d983f423a2
Коммит
26553fb8ea
@ -6,11 +6,13 @@
|
|||||||
import { growDuration, bloomDuration, jitterFactor } from '../transitions/constants';
|
import { growDuration, bloomDuration, jitterFactor } from '../transitions/constants';
|
||||||
import { curvyDoubleLine } from '../utils/paths';
|
import { curvyDoubleLine } from '../utils/paths';
|
||||||
import { createTweenedPos } from '../transitions/tween';
|
import { createTweenedPos } from '../transitions/tween';
|
||||||
|
import { usaBlue } from '../utils/colors';
|
||||||
|
|
||||||
export let source;
|
export let source;
|
||||||
export let selected = 'unselected';
|
export let selected = 'unselected';
|
||||||
export let hovered = 'unselected';
|
export let hovered = 'unselected';
|
||||||
export let extraFaint = false;
|
export let extraFaint = false;
|
||||||
|
export let showPolarizationColor = false;
|
||||||
|
|
||||||
const tweenedPos = createTweenedPos();
|
const tweenedPos = createTweenedPos();
|
||||||
|
|
||||||
@ -45,6 +47,7 @@
|
|||||||
$tweenedPos.fy + source.rSmiTot - 5,
|
$tweenedPos.fy + source.rSmiTot - 5,
|
||||||
source.shift,
|
source.shift,
|
||||||
$mapHeight / 15)}
|
$mapHeight / 15)}
|
||||||
|
stroke={showPolarizationColor ? source.polarizationColor : usaBlue}
|
||||||
stroke-width={$minDim / 200}
|
stroke-width={$minDim / 200}
|
||||||
in:draw|local={{duration: growDuration, delay: source.id * jitterFactor, easing: linear}}
|
in:draw|local={{duration: growDuration, delay: source.id * jitterFactor, easing: linear}}
|
||||||
out:draw|local={{duration: growDuration, delay: bloomDuration + source.id * jitterFactor, easing: linear}}></path>
|
out:draw|local={{duration: growDuration, delay: bloomDuration + source.id * jitterFactor, easing: linear}}></path>
|
||||||
@ -53,7 +56,6 @@
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
path {
|
path {
|
||||||
stroke: var(--usa-blue);
|
|
||||||
fill: none;
|
fill: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
import { sortConsistently } from '../utils/misc';
|
import { sortConsistently } from '../utils/misc';
|
||||||
import { hovered as eHovered, selected as eSelected } from '../stores/eventSelections';
|
import { hovered as eHovered, selected as eSelected } from '../stores/eventSelections';
|
||||||
import { hovered as cHovered } from '../stores/centroidSelections';
|
import { hovered as cHovered } from '../stores/centroidSelections';
|
||||||
import { disinformantNationFilter, selectAllFilters, unselectAllFilters } from '../stores/filters';
|
import { disinformantNationFilter, selectAllFilters, unselectAllFilters, highlightPolarization } from '../stores/filters';
|
||||||
|
|
||||||
import SourceLink from './SourceLink.svelte';
|
import SourceLink from './SourceLink.svelte';
|
||||||
import Centroid from './Centroid.svelte';
|
import Centroid from './Centroid.svelte';
|
||||||
@ -105,7 +105,8 @@
|
|||||||
: ($eHovered
|
: ($eHovered
|
||||||
? 'background'
|
? 'background'
|
||||||
: 'unselected')}
|
: 'unselected')}
|
||||||
extraFaint={source.outOfTimeRange} />
|
extraFaint={source.outOfTimeRange}
|
||||||
|
showPolarizationColor={$highlightPolarization} />
|
||||||
{/each}
|
{/each}
|
||||||
{#each centroids as [country, centroid]}
|
{#each centroids as [country, centroid]}
|
||||||
<Centroid {centroid}
|
<Centroid {centroid}
|
||||||
|
|||||||
@ -22,7 +22,8 @@
|
|||||||
smiTotalYScale,
|
smiTotalYScale,
|
||||||
smiTotalRScale,
|
smiTotalRScale,
|
||||||
smiShareRScale,
|
smiShareRScale,
|
||||||
attributionScoreScale } from '../stores/scales';
|
attributionScoreScale,
|
||||||
|
polarizationScale } from '../stores/scales';
|
||||||
import {
|
import {
|
||||||
disinformantNationFilter,
|
disinformantNationFilter,
|
||||||
platformFilter,
|
platformFilter,
|
||||||
@ -57,7 +58,7 @@
|
|||||||
forceCenter,
|
forceCenter,
|
||||||
forceCollide,
|
forceCollide,
|
||||||
timeFormat } from 'd3';
|
timeFormat } from 'd3';
|
||||||
import { sortConsistently } from '../utils/misc';
|
import { sortConsistently, averagePolarization } from '../utils/misc';
|
||||||
import { parseUrl } from '../utils/share';
|
import { parseUrl } from '../utils/share';
|
||||||
|
|
||||||
import ToTop from './ToTop.svelte';
|
import ToTop from './ToTop.svelte';
|
||||||
@ -163,7 +164,8 @@
|
|||||||
rSmiTwShare: $smiShareRScale(d.smiTwitterShare),
|
rSmiTwShare: $smiShareRScale(d.smiTwitterShare),
|
||||||
rSmiReShare: $smiShareRScale(d.smiRedditShare),
|
rSmiReShare: $smiShareRScale(d.smiRedditShare),
|
||||||
fy: d.smiPending ? Math.min($smiTotalYScale.range()[0], $smiTotalYScale.range()[0] - 2 * $smiTotalRScale.range()[0] + (Math.random() - 0.5) * 20) : $smiTotalYScale(d.smiTotal),
|
fy: d.smiPending ? Math.min($smiTotalYScale.range()[0], $smiTotalYScale.range()[0] - 2 * $smiTotalRScale.range()[0] + (Math.random() - 0.5) * 20) : $smiTotalYScale(d.smiTotal),
|
||||||
outOfTimeRange: $timeScale(d.attributionDate) < $timeScale.range()[0] || $timeScale(d.attributionDate) > $timeScale.range()[1]
|
outOfTimeRange: $timeScale(d.attributionDate) < $timeScale.range()[0] || $timeScale(d.attributionDate) > $timeScale.range()[1],
|
||||||
|
polarizationColor: $polarizationScale(averagePolarization(d.polarization.general))
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => sortConsistently(a, b, 'rSmiTot', 'id'));
|
.sort((a, b) => sortConsistently(a, b, 'rSmiTot', 'id'));
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +1,27 @@
|
|||||||
export const categories = [
|
export const categories = [
|
||||||
{
|
{
|
||||||
id: 'l',
|
id: 'l',
|
||||||
name: 'left'
|
name: 'left',
|
||||||
|
weight: -2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'll',
|
id: 'll',
|
||||||
name: 'leanleft'
|
name: 'leanleft',
|
||||||
|
weight: -1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'c',
|
id: 'c',
|
||||||
name: 'center'
|
name: 'center',
|
||||||
|
weight: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'lr',
|
id: 'lr',
|
||||||
name: 'leanright'
|
name: 'leanright',
|
||||||
|
weight: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'r',
|
id: 'r',
|
||||||
name: 'right'
|
name: 'right',
|
||||||
|
weight: 2
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -8,4 +8,6 @@ export const attributionScoreScale = writable();
|
|||||||
|
|
||||||
export const centroidScale = writable();
|
export const centroidScale = writable();
|
||||||
|
|
||||||
|
export const polarizationScale = writable();
|
||||||
|
|
||||||
export const scaleFactor = readable(window.devicePixelRatio || 1);
|
export const scaleFactor = readable(window.devicePixelRatio || 1);
|
||||||
|
|||||||
@ -1,4 +1,11 @@
|
|||||||
export const bg = '#F9F8F8';
|
export const bg = '#F9F8F8';
|
||||||
|
export const usaBlue = '#3c3b6e';
|
||||||
export const usaRed = '#b22234';
|
export const usaRed = '#b22234';
|
||||||
export const usaLightRed = '#b22234';
|
export const usaLightRed = '#b22234';
|
||||||
export const usaLightLightRed = '#dbb6b6';
|
export const usaLightLightRed = '#dbb6b6';
|
||||||
|
|
||||||
|
export const polBlue = '#2e64a0';
|
||||||
|
export const polLightBlue = '#61a3de';
|
||||||
|
export const polPurple = '#96659e';
|
||||||
|
export const polLightRed = '#a15552';
|
||||||
|
export const polRed = '#ca0800';
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { uniq } from 'lodash';
|
import { uniq } from 'lodash';
|
||||||
import { mean, min, max } from 'd3';
|
import { mean, min, max } from 'd3';
|
||||||
import { images } from '../inputs/dataPaths';
|
import { images } from '../inputs/dataPaths';
|
||||||
|
import { categories } from '../inputs/polarization';
|
||||||
|
|
||||||
// extract attribution date range from data
|
// extract attribution date range from data
|
||||||
export const getTimeRange = (data) => {
|
export const getTimeRange = (data) => {
|
||||||
@ -124,3 +125,16 @@ export const scrollTo = (targetId, collapsibleId) => {
|
|||||||
return(false);
|
return(false);
|
||||||
};
|
};
|
||||||
window.scrollsmooth = scrollTo;
|
window.scrollsmooth = scrollTo;
|
||||||
|
|
||||||
|
// calculate average polarization using weights
|
||||||
|
export const averagePolarization = (polarization) => {
|
||||||
|
const weightedEngagement = Object.keys(polarization).map((id) => {
|
||||||
|
const weight = categories.find((c) => c.id === id).weight;
|
||||||
|
return(weight * polarization[id]);
|
||||||
|
})
|
||||||
|
.reduce((acc, cur) => acc + cur);
|
||||||
|
|
||||||
|
const totalEngagement = Object.keys(polarization).map((id) => polarization[id]).reduce((acc, cur) => acc + cur);
|
||||||
|
|
||||||
|
return(weightedEngagement / totalEngagement);
|
||||||
|
};
|
||||||
|
|||||||
@ -4,8 +4,15 @@ import {
|
|||||||
smiTotalRScale,
|
smiTotalRScale,
|
||||||
smiShareRScale,
|
smiShareRScale,
|
||||||
attributionScoreScale,
|
attributionScoreScale,
|
||||||
centroidScale } from '../stores/scales';
|
centroidScale,
|
||||||
import { usaRed } from '../utils/colors';
|
polarizationScale } from '../stores/scales';
|
||||||
|
import {
|
||||||
|
usaRed,
|
||||||
|
polBlue,
|
||||||
|
polLightBlue,
|
||||||
|
polPurple,
|
||||||
|
polLightRed,
|
||||||
|
polRed } from '../utils/colors';
|
||||||
import {
|
import {
|
||||||
scaleTime,
|
scaleTime,
|
||||||
scaleLinear,
|
scaleLinear,
|
||||||
@ -50,4 +57,9 @@ export const setScales = (data, width, minDim, maxDim, panelHeight, margin) => {
|
|||||||
centroidScale.set(scaleSqrt()
|
centroidScale.set(scaleSqrt()
|
||||||
.domain([0, max(casesPerCountry)])
|
.domain([0, max(casesPerCountry)])
|
||||||
.range([maxDim * 0.0005, maxDim * 0.01]));
|
.range([maxDim * 0.0005, maxDim * 0.01]));
|
||||||
|
|
||||||
|
// polarization scale
|
||||||
|
polarizationScale.set(scaleLinear()
|
||||||
|
.domain([-2, 0, 2])
|
||||||
|
.range([polBlue, polPurple, polRed]));
|
||||||
};
|
};
|
||||||
|
|||||||
Загрузка…
x
Ссылка в новой задаче
Block a user