summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2019-06-28 02:06:53 -0400
committerJules Laplace <julescarbon@gmail.com>2019-06-28 02:06:53 -0400
commitfe418ace1873b81fa3d2c622d3b414dcacbe7b56 (patch)
tree1751236c335fc503502de0ea6867f6e043c0e9ac
parent3d2967573738154b4dd50bdd4a600aff42f276ae (diff)
more options... add download csv link and search
-rw-r--r--client/chart/constants.js45
-rw-r--r--client/chart/singlePie.chart.js22
-rw-r--r--client/index.js9
-rw-r--r--client/table/citations.table.js6
-rw-r--r--client/table/file.table.js60
-rw-r--r--client/table/tabulator.css12
-rw-r--r--site/content/_drafts_/lfw/index.md2
-rw-r--r--site/content/pages/research/_introduction/index.md2
-rw-r--r--site/content/pages/research/munich_security_conference/index.md4
-rw-r--r--site/content/pages/test/csv.md2
10 files changed, 112 insertions, 52 deletions
diff --git a/client/chart/constants.js b/client/chart/constants.js
index 6fe94433..0f23f06b 100644
--- a/client/chart/constants.js
+++ b/client/chart/constants.js
@@ -48,12 +48,35 @@ export const colorblindSafeRainbow = [
// '#888888',
]
+export const categoryRainbow = [
+ '#5e4fa2',
+ '#66c2a5',
+ '#d53e4f',
+ '#f46d43',
+ '#9e0142',
+ '#3288bd',
+ '#fee08b',
+ '#abdda4',
+ '#e6f598',
+ '#fdae61',
+ '#ffffbf',
+ // '#888888',
+]
+
export const institutionColors = [
'#f2f293', // edu (yellow)
'#3264f6', // company (blue)
'#f30000', // gov/mil (red)
]
+export const colorTable = {
+ rainbow,
+ bigRainbow,
+ colorblindSafeRainbow,
+ institutionColors,
+ categoryRainbow,
+}
+
/* stuff for a 'countries' legend */
export const topCountryCount = 10
@@ -63,20 +86,20 @@ export const otherCountriesLabel = 'Other Countries'
/* institution tuples, labels and templates */
export const initialInstitutionLookup = {
- 'edu': 0,
- 'company': 0,
- 'gov': 0,
+ edu: 0,
+ company: 0,
+ gov: 0,
}
export const institutionOrder = {
- 'edu': 0,
- 'company': 1,
- 'gov': 2,
+ edu: 0,
+ company: 1,
+ gov: 2,
}
export const institutionLabels = {
- 'edu': 'Academic',
- 'company': 'Commercial',
- 'gov': 'Military / Government',
- 'mil': 'Military / Government',
-} \ No newline at end of file
+ edu: 'Academic',
+ company: 'Commercial',
+ gov: 'Military / Government',
+ mil: 'Military / Government',
+}
diff --git a/client/chart/singlePie.chart.js b/client/chart/singlePie.chart.js
index ed2da582..2e770bd7 100644
--- a/client/chart/singlePie.chart.js
+++ b/client/chart/singlePie.chart.js
@@ -6,33 +6,24 @@ import 'c3/c3.css'
import './chart.css'
import {
- rainbow, bigRainbow
+ rainbow, bigRainbow, colorTable
} from './constants'
class SinglePieChart extends Component {
state = {
keys: [],
data: [],
- fields: {},
}
componentDidMount() {
const { payload } = this.props
- console.log(payload)
- console.log(payload.fields)
- const fields = {}
- payload.fields.forEach(field => {
- const [k, v] = field.split(': ')
- fields[k] = v
- })
-
fetch(payload.url, { mode: 'cors' })
.then(r => r.text())
.then(text => {
try {
const keys = text.split('\n')[0].split(',').map(s => s.trim().replace(/"/, ''))
const data = csv.toJSON(text, { headers: { included: true } })
- this.setState({ keys, data, fields })
+ this.setState({ keys, data })
} catch (e) {
console.error("error making json:", payload.url)
console.error(e)
@@ -41,8 +32,9 @@ class SinglePieChart extends Component {
}
render() {
- const { keys, data, fields } = this.state
- console.log(keys, data)
+ const { fields } = this.props.payload
+ const { keys, data } = this.state
+ // console.log(keys, data)
const [labelField, numberField] = keys
if (!data.length) return null
@@ -63,6 +55,8 @@ class SinglePieChart extends Component {
const height = chartRows.length < 6 ? 316 :
chartRows.length < 10 ? 336 : 356
+ const pattern = colorTable[fields.Colors] || (chartRows.length < 10 ? rainbow : bigRainbow)
+
return (
<div className='chart'>
<div>
@@ -72,7 +66,7 @@ class SinglePieChart extends Component {
type: 'pie',
}}
color={{
- pattern: chartRows.length < 10 ? rainbow : bigRainbow,
+ pattern,
}}
tooltip={{
format: {
diff --git a/client/index.js b/client/index.js
index 835d859c..9644ba5c 100644
--- a/client/index.js
+++ b/client/index.js
@@ -73,6 +73,15 @@ function runApplets() {
let opt = null
payload.cmd = cmd
payload.partz = cmdPartz
+ const fields = {}
+ if (payload.fields) {
+ payload.fields.forEach(field => {
+ const [k, v] = field.split(': ')
+ fields[k] = v
+ })
+ }
+ payload.fields = fields
+
if (payload.cmd === 'load_file' || payload.cmd === 'single_pie_chart') {
payload.url = 'https://nyc3.digitaloceanspaces.com/megapixels/v1' + cmdPartz.shift()
return [el, payload]
diff --git a/client/table/citations.table.js b/client/table/citations.table.js
index ef5ab0b5..c1c71906 100644
--- a/client/table/citations.table.js
+++ b/client/table/citations.table.js
@@ -1,11 +1,9 @@
import React, { Component } from 'react'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
import { ReactTabulator } from 'react-tabulator'
import { saveAs } from 'file-saver'
import { Loader } from '../common'
-import { toArray, toTuples, domainFromUrl } from '../util'
+import { domainFromUrl } from '../util'
export const citationsColumns = [
{ title: 'Title', field: 'title', sorter: 'string' },
@@ -111,7 +109,7 @@ class CitationsTable extends Component {
value={this.state.q}
onChange={e => this.updateFilter(e.target.value)}
className='q'
- placeholder='Enter text to search citations...'
+ placeholder='Enter text to search citations'
/>
<span className='download' onClick={() => this.download()}>Download CSV</span>
</div>
diff --git a/client/table/file.table.js b/client/table/file.table.js
index c880810a..c195b09d 100644
--- a/client/table/file.table.js
+++ b/client/table/file.table.js
@@ -1,17 +1,17 @@
import React, { Component } from 'react'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
import { ReactTabulator } from 'react-tabulator'
import csv from 'parse-csv'
-import { toArray, toTuples, domainFromUrl } from '../util'
+import { domainFromUrl } from '../util'
import { Loader } from '../common'
class FileTable extends Component {
state = {
keys: [],
data: [],
+ filteredData: [],
columns: [],
+ q: '',
}
componentDidMount() {
@@ -25,7 +25,7 @@ class FileTable extends Component {
const data = csv.toJSON(text, { headers: { included: true } })
// console.log(data)
const columns = this.getColumns(keys, data, payload.fields)
- this.setState({ keys, data, columns })
+ this.setState({ keys, data, filteredData: data, columns })
} catch (e) {
console.error("error making json:", payload.url)
console.error(e)
@@ -34,10 +34,11 @@ class FileTable extends Component {
}
getColumns(keys, data, fields) {
- let titles = fields.length ? fields[0].split(', ') : keys
+ let titles = fields.Headings ? fields.Headings.split(', ') : keys
// let numberFields = []
let columns = keys.map((field, i) => {
const title = titles[i] || field
+ let widthGrow = 1
if (field.match('url')) {
let textField = field.replace('url', 'label')
data.forEach(el => el[textField] = domainFromUrl(el[field]))
@@ -49,31 +50,60 @@ class FileTable extends Component {
sorter: 'string'
}
}
+ if (title === 'Embassy') {
+ widthGrow = 2
+ }
switch (field) {
case 'images':
case 'year':
return { title, field: field.toLowerCase(), sorter: 'number' }
default:
- return { title, field: field.toLowerCase(), sorter: 'string' }
+ return { title, field: field.toLowerCase(), sorter: 'string', widthGrow }
}
})
return columns
}
+ updateFilter(q) {
+ const { keys, data } = this.state
+ if (!q.length) {
+ this.setState({ q, filteredData: data })
+ } else {
+ let qRe = new RegExp('(' + q.replace(/\s+/g, ' ').trim().replace(' ', '|') + ')', 'gi')
+ let filteredData = data.filter(row => keys.some(key => row[key].match(qRe)))
+ this.setState({ q, filteredData })
+ }
+ }
+
render() {
+ const { payload } = this.props
+ const { q, columns, data, filteredData } = this.state
if (!this.state.data.length) {
return <Loader />
}
+ const fn = payload.url.split('/').pop()
return (
- <ReactTabulator
- columns={this.state.columns}
- data={this.state.data}
- options={{
- height: Math.min(37 * this.state.data.length + 29, 311),
- layout: 'fitColumns',
- placeholder: 'No Data Set',
- }}
- />
+ <div className='citationBrowser'>
+ <div className='citationHeader'>
+ <input
+ type="text"
+ value={q}
+ onChange={e => this.updateFilter(e.target.value)}
+ className='q'
+ placeholder='Enter text to search data'
+ />
+ <a className='download' href={payload.url} filename={fn}>Download CSV</a>
+ </div>
+ <ReactTabulator
+ columns={columns}
+ data={filteredData}
+ options={{
+ height: Math.min(37 * data.length + 29, 311),
+ layout: 'fitColumns',
+ placeholder: 'No Data Set',
+ }}
+ />
+ </div>
)
}
}
diff --git a/client/table/tabulator.css b/client/table/tabulator.css
index 95768976..0ea81974 100644
--- a/client/table/tabulator.css
+++ b/client/table/tabulator.css
@@ -40,7 +40,7 @@
max-width: 400px;
margin-bottom: 10px;
background-image: url(/assets/img/icon-search.png);
- background-position: 380px center;
+ background-position: 378px center;
background-repeat: no-repeat;
box-shadow: 0px 2px 4px rgba(0,0,0,0.2);
border: 0;
@@ -53,17 +53,21 @@
align-items: flex-start;
justify-content: space-between;
}
-span.download {
+.download {
display: block;
font-size: 13px;
color: #ddd;
cursor: pointer;
background: #333;
- padding: 5px 8px;
+ padding: 5px 8px 5px 8px;
border-radius: 5px;
transition: all 0.2s;
+ border: 0 !important;
}
-.desktop span.download:hover {
+.content a.download {
+ padding: 5px 8px 5px 8px;
+}
+.desktop .download:hover {
color: #fff;
background: #666;
} \ No newline at end of file
diff --git a/site/content/_drafts_/lfw/index.md b/site/content/_drafts_/lfw/index.md
index ad43e2dd..a5d6bd18 100644
--- a/site/content/_drafts_/lfw/index.md
+++ b/site/content/_drafts_/lfw/index.md
@@ -54,7 +54,7 @@ Add a paragraph about how usage extends far beyond academia into research center
```
load_file assets/lfw_commercial_use.csv
-name_display, company_url, example_url, country, description
+Headings: name_display, company_url, example_url, country, description
```
diff --git a/site/content/pages/research/_introduction/index.md b/site/content/pages/research/_introduction/index.md
index 7e839fe7..bdf1c1b0 100644
--- a/site/content/pages/research/_introduction/index.md
+++ b/site/content/pages/research/_introduction/index.md
@@ -37,7 +37,7 @@ Add info from the AI Traps talk
```
load_file /site/research/00_introduction/assets/summary_countries_top.csv
-country, Xcitations
+Headings: country, Xcitations
```
Paragraph text to test css formatting. Paragraph text to test css formatting. Paragraph text to test css formatting. Paragraph text to test css formatting. Paragraph text to test css formatting.
diff --git a/site/content/pages/research/munich_security_conference/index.md b/site/content/pages/research/munich_security_conference/index.md
index 6a1b84e9..3c4d7f08 100644
--- a/site/content/pages/research/munich_security_conference/index.md
+++ b/site/content/pages/research/munich_security_conference/index.md
@@ -115,6 +115,7 @@ single_pie_chart /site/research/munich_security_conference/assets/megapixels_ori
Caption: Sources of Face Training Data
Top: 5
OtherLabel: Other Countries
+Colors: categoryRainbow
```
===========
@@ -124,6 +125,7 @@ single_pie_chart /site/research/munich_security_conference/assets/embassy_counts
Caption: Dataset sources
Top: 4
OtherLabel: Other
+Colors: categoryRainbow
```
=== end columns
@@ -134,7 +136,7 @@ OtherLabel: Other
```
load_file /site/research/munich_security_conference/assets/embassy_counts_public.csv
-Images, Dataset, Embassy, Flickr ID, URL, Guest, Host
+Headings: Images, Dataset, Embassy, Flickr ID, URL, Guest, Host
```
diff --git a/site/content/pages/test/csv.md b/site/content/pages/test/csv.md
index 85f714b4..ef3327f8 100644
--- a/site/content/pages/test/csv.md
+++ b/site/content/pages/test/csv.md
@@ -16,5 +16,5 @@ authors: Megapixels
```
load_file /site/test/assets/test.csv
-Name, Images, Year, Gender, Description, URL
+Headings: Name, Images, Year, Gender, Description, URL
```