How to use d3.symbols with an ordinal scale
up vote
1
down vote
favorite
TL;DR: How do I get a scaleOrdinal over the d3.symbols?
I'm hoping to use d3.symbols for an ordinal scale, corresponding to a categorical attribute on some data.
d3.symbols
An array containing the set of all built-in symbol types: circle, cross, diamond, square, star, triangle, and wye. Useful for constructing the range of an ordinal scale should you wish to use a shape encoding for categorical data.
Here's what I thought would work:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
(alternately see fiddle).
Unfortunately the above fails with:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "[object Object]".
Clearly shape(d.type)
is not returning a valid path. It's actually returning an object with a single function named draw, i.e. it looks like { draw: function() { ... } }
, which presumably refers to this draw method. Calling that draw method doesn't yield a valid path either, though, unfortunately.
javascript d3.js svg
add a comment |
up vote
1
down vote
favorite
TL;DR: How do I get a scaleOrdinal over the d3.symbols?
I'm hoping to use d3.symbols for an ordinal scale, corresponding to a categorical attribute on some data.
d3.symbols
An array containing the set of all built-in symbol types: circle, cross, diamond, square, star, triangle, and wye. Useful for constructing the range of an ordinal scale should you wish to use a shape encoding for categorical data.
Here's what I thought would work:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
(alternately see fiddle).
Unfortunately the above fails with:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "[object Object]".
Clearly shape(d.type)
is not returning a valid path. It's actually returning an object with a single function named draw, i.e. it looks like { draw: function() { ... } }
, which presumably refers to this draw method. Calling that draw method doesn't yield a valid path either, though, unfortunately.
javascript d3.js svg
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
TL;DR: How do I get a scaleOrdinal over the d3.symbols?
I'm hoping to use d3.symbols for an ordinal scale, corresponding to a categorical attribute on some data.
d3.symbols
An array containing the set of all built-in symbol types: circle, cross, diamond, square, star, triangle, and wye. Useful for constructing the range of an ordinal scale should you wish to use a shape encoding for categorical data.
Here's what I thought would work:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
(alternately see fiddle).
Unfortunately the above fails with:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "[object Object]".
Clearly shape(d.type)
is not returning a valid path. It's actually returning an object with a single function named draw, i.e. it looks like { draw: function() { ... } }
, which presumably refers to this draw method. Calling that draw method doesn't yield a valid path either, though, unfortunately.
javascript d3.js svg
TL;DR: How do I get a scaleOrdinal over the d3.symbols?
I'm hoping to use d3.symbols for an ordinal scale, corresponding to a categorical attribute on some data.
d3.symbols
An array containing the set of all built-in symbol types: circle, cross, diamond, square, star, triangle, and wye. Useful for constructing the range of an ordinal scale should you wish to use a shape encoding for categorical data.
Here's what I thought would work:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
(alternately see fiddle).
Unfortunately the above fails with:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "[object Object]".
Clearly shape(d.type)
is not returning a valid path. It's actually returning an object with a single function named draw, i.e. it looks like { draw: function() { ... } }
, which presumably refers to this draw method. Calling that draw method doesn't yield a valid path either, though, unfortunately.
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{type: 'a'}, {type: 'a'}, {type: 'a'}, {type: 'b'}, {type: 'b'}, {type: 'c'}];
var shape = d3.scaleOrdinal(d3.symbols);
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => shape(d.type))
.attr('x', (d, i) => i * 20)
.attr('y', 50);
/* Sanity Check: Properly renders */
s.enter()
.append('circle')
.attr('r',7)
.attr('cx', (d, i) => (i+1)*20)
.attr('cy', 100);
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graph-container"></div>
javascript d3.js svg
javascript d3.js svg
edited Nov 21 at 0:18
Gerardo Furtado
62.8k64183
62.8k64183
asked Nov 20 at 23:55
Alex Lenail
2,65141845
2,65141845
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
You're missing the symbol generator itself...
var symbol = d3.symbol();
... to which you'll pass the type:
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
//etc...
Also, <path>
s don't have x
or y
attributes.
Here is the code with those changes:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
You're missing the symbol generator itself...
var symbol = d3.symbol();
... to which you'll pass the type:
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
//etc...
Also, <path>
s don't have x
or y
attributes.
Here is the code with those changes:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
add a comment |
up vote
2
down vote
accepted
You're missing the symbol generator itself...
var symbol = d3.symbol();
... to which you'll pass the type:
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
//etc...
Also, <path>
s don't have x
or y
attributes.
Here is the code with those changes:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
You're missing the symbol generator itself...
var symbol = d3.symbol();
... to which you'll pass the type:
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
//etc...
Also, <path>
s don't have x
or y
attributes.
Here is the code with those changes:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
You're missing the symbol generator itself...
var symbol = d3.symbol();
... to which you'll pass the type:
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
//etc...
Also, <path>
s don't have x
or y
attributes.
Here is the code with those changes:
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
var svg = d3.select('#graph-container').append('svg').attr('xmlns', 'http://www.w3.org/2000/svg');
var g = svg.append('g');
var data = [{
type: 'a'
}, {
type: 'a'
}, {
type: 'a'
}, {
type: 'b'
}, {
type: 'b'
}, {
type: 'c'
}];
var shape = d3.scaleOrdinal(d3.symbols);
var symbol = d3.symbol();
var s = g.selectAll('.symbol').data(data);
/* Does not render */
s.enter()
.append('path')
.attr('d', d => symbol.type(shape(d.type))())
.attr("transform", (_, i) => "translate(" + (20 + i * 20) + ",50)")
.attr('fill', 'black');
/* Properly renders */
s.enter()
.append('circle')
.attr('r', 7)
.attr('cx', (d, i) => (i + 1) * 20)
.attr('cy', 100)
.attr('fill', 'black');
<div id="graph-container"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
answered Nov 21 at 0:18
Gerardo Furtado
62.8k64183
62.8k64183
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
add a comment |
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
follow-up question: why do symbols.size() require such big sizes? What do those sizes refer to? There are hints that it might be the area of the symbol in the docs
– Alex Lenail
Nov 21 at 0:25
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
2 days ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403371%2fhow-to-use-d3-symbols-with-an-ordinal-scale%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown