Skip to content

Commit 24c75c4

Browse files
committed
rendering point marks, with attributes from ordinal variables
1 parent a9b8bf4 commit 24c75c4

File tree

6 files changed

+135
-14
lines changed

6 files changed

+135
-14
lines changed

public/js/explore-sql.min.js

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/explorer/components/Shelf.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ FieldContainer = DropTarget(["TableField", "ShelfField"], FieldDropHandler, fiel
6161

6262
const LEGEND_TYPE = {
6363
color: 'color',
64-
opacity: 'color'
64+
opacity: 'color',
65+
shape: 'symbol',
66+
size: 'size'
6567
}
6668

6769
class ShelfLegend extends React.Component {
@@ -77,7 +79,18 @@ class ShelfLegend extends React.Component {
7779
if (null == scaleObject) return
7880
let { type, domain, range } = scaleObject
7981
let scale = d3.scale[type]().domain(domain).range(range)
82+
switch(shelf) {
83+
case 'shape':
84+
scale.range(_.map(scale.range(), shape => d3.svg.symbol().type(shape)()))
85+
break
86+
case 'size':
87+
scale.range(_.map(scale.range(), v => Math.sqrt(v / Math.PI)))
88+
}
8089
let svgLegend = d3.legend[LEGEND_TYPE[shelf]]().scale(scale)
90+
switch(shelf) {
91+
case 'size':
92+
svgLegend.shape('circle').shapePadding(5)
93+
}
8194
switch(type) {
8295
case 'linear': case 'log': case 'pow': case 'sqrt':
8396
let ticks = scale.ticks(5)
@@ -90,9 +103,9 @@ class ShelfLegend extends React.Component {
90103
}
91104
let node = d3.select(this.refs.d3LegendContainer)
92105
let elem = findDOMNode(this)
93-
let legendElem = node.append('g').call(svgLegend)
106+
let legendElem = node.append('g').attr("transform", _.contains(['shape', 'size'], shelf) ? "translate(10, 10)" : null).call(svgLegend)
94107
let legendBounds = legendElem[0][0].getBoundingClientRect()
95-
node.attr("width", legendBounds.width).attr("height", legendBounds.height)
108+
node.attr("width", legendBounds.width).attr("height", legendBounds.height + 5)
96109
}
97110

98111
componentDidMount() {

src/explorer/components/vis/Pane.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { getFieldQueryType, getAccessorName } from '../../helpers/field'
33

44
const MARKS = {
55
'bar': React.createFactory(require('./marks/Bar')),
6-
'line': React.createFactory(require('./marks/Line'))
6+
'line': React.createFactory(require('./marks/Line')),
7+
'point': React.createFactory(require('./marks/Point'))
78
}
89

910
export class Pane extends React.Component {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import _ from 'lodash'
2+
import dl from 'datalib'
3+
import d3 from 'd3'
4+
import React from 'react'
5+
import { getAccessorName, isBinField } from '../../../helpers/field'
6+
const { svg } = React.DOM
7+
8+
export default class Point extends React.Component {
9+
getDefaultScales() {
10+
const { scales } = this.props
11+
let symbol = d3.svg.symbol()
12+
return {
13+
size: scales.size.__default__,
14+
opacity: scales.opacity.__default__,
15+
symbol: symbol,
16+
shape: scales.shape.__default__,
17+
color: scales.color.__default__,
18+
x: 0,
19+
y: 0
20+
}
21+
}
22+
23+
getSymbolScales(props) {
24+
const { markData, width, height } = this.props
25+
const { field, scale, shelf } = props
26+
const name = getAccessorName(field)
27+
switch(shelf) {
28+
case 'row':
29+
return {
30+
y: (d) => scale(d[name])
31+
}
32+
case 'col':
33+
return {
34+
x: (d) => scale(d[name])
35+
}
36+
case 'color':
37+
let color = (d) => scale(d[name])
38+
return {
39+
color
40+
}
41+
case 'size':
42+
return {
43+
size: d => scale(d[name])
44+
}
45+
case 'shape':
46+
return {
47+
shape: d => scale(d[name])
48+
}
49+
case 'opacity':
50+
default:
51+
return {
52+
}
53+
}
54+
}
55+
56+
getAttributeTransforms() {
57+
const { transformFields } = this.props
58+
let transforms = _.merge(
59+
this.getDefaultScales(),
60+
_.reduce(_.map(transformFields, (fs) => this.getSymbolScales(fs)), _.merge, {}))
61+
transforms.transform = (d, i) => `translate(${transforms.x(d, i)}, ${transforms.y(d, i)})`
62+
transforms.d = d => {
63+
return transforms.symbol.size(transforms.size(d)).type(transforms.shape(d))()
64+
}
65+
return transforms
66+
}
67+
68+
_d3Render() {
69+
d3.select(this.refs.d3container).selectAll("*").remove()
70+
const transforms = this.getAttributeTransforms()
71+
let symbols = d3.select(this.refs.d3container).selectAll("g.symbol")
72+
.data(this.props.markData)
73+
.enter().append("g").attr("class", "symbol")
74+
.append('path')
75+
.attr('stroke-width', 1)
76+
.attr('d', transforms.d)
77+
.attr('fill', transforms.color)
78+
.attr('fill-opacity', 0.2)
79+
.attr('stroke', transforms.color)
80+
.attr('transform', transforms.transform)
81+
}
82+
83+
componentDidMount() {
84+
this._d3Render()
85+
}
86+
87+
componentDidUpdate() {
88+
this._d3Render()
89+
}
90+
91+
componentWillUnmount() {
92+
d3.select(this.refs.d3container).selectAll("*").remove()
93+
}
94+
95+
render() {
96+
const { width, height } = this.props
97+
return svg({ref: 'd3container', width, height})
98+
}
99+
}

src/explorer/data/scale.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ function getOrdinalVisualRange(shelf, spec) {
88
switch (shelf) {
99
case 'color':
1010
return COLOR_PALETTES[spec.palette]
11+
case 'shape':
12+
return spec.shapes
13+
case 'size':
14+
return spec.sizes
1115
default:
1216
return []
1317
}

src/explorer/ducks/visualspec.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,13 @@ function table(state = tableState, action) {
3939

4040
const propertiesState = {
4141
size: {
42-
'default': 30,
42+
sizes: [30, 50, 80, 120, 170, 230, 300],
43+
'default': 30
44+
},
45+
shape: {
46+
shapes: ["circle", "cross", "diamond", "square", "triangle-down", "triangle-up"],
47+
'default': 'circle'
4348
},
44-
shape: {},
4549
color: {
4650
palette: "category10",
4751
'default': "#356CA7",

0 commit comments

Comments
 (0)