How to use d3.symbols with an ordinal scale
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 |
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 |
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
63.2k64384
63.2k64384
asked Nov 20 at 23:55
Alex Lenail
2,75742046
2,75742046
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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
Nov 21 at 20:13
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
Nov 21 at 20:13
add a comment |
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
Nov 21 at 20:13
add a comment |
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
63.2k64384
63.2k64384
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
Nov 21 at 20:13
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
Nov 21 at 20:13
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
Nov 21 at 20:13
Because it is indeed the area of the symbol. Unfortunately the API doesn't make it clear.
– Gerardo Furtado
Nov 21 at 20:13
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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