Refactor `chart.marks`
jwildfire opened this issue · 0 comments
jwildfire commented
It's currently a pain to select marks for customization once they are rendered. There's no reason for this to be the case. The following changes should help:
- Allow custom IDs for mark groups: Add a new optional
config.marks[].id
property. This will be added as a class to the marks "supergroup" and can be used for filtering the marks array. If user doesn't specify an the index of the mark group is used ("markgroup1", "markgroup2" ,etc.) - Link
config.marks
tochart.marks
: Update thechart.marks
spec so that eachchart.mark
object (ie each item in thechart.marks[]
array) includes all properties from the correspondingconfig.marks[]
object, as described here, should be included. The wiki implies these are already included, but as of 1.9.0 they are not. Note thatchart.marks[].data
is currently the only property for the mark objects, and will remain unchanged (even though it's kind of a hot mess). - Create a
supergroup
property for each mark: This links the d3 selection for the "supergroup" containing all marks. Simplifies the code fromconst pointGroup = chart.svg.select("g.point-supergroup")
toconst pointGroup = chart.marks[0].supergroup
. - Create an
groups
property for each mark: This links the d3 selection for all of the groups containing individual marks. Simplifies the code fromconst points = chart.svg.select("g.point-supergroup").selectAll("g.points")
) toconst myPoints = chart.marks[0].wrap
or better yetchart.marks.filter().pop().items()
- Create mark-level properties when possible: selects
circle
for mark.type="points",text
for mark.type="text" and paths for mark.type="line". No support for bars at this level yet since nesting/grouping etc makes it messy, but could tackle later. - Create a new
marks.supergroups
property: Link a d3 selection of all the mark supergroups to the chart.mark object itself. This should allow for much easier access to the d3.selection for the mark data.
All told these changes should greatly simplify mark customization in callbacks. For example:
//Fill all circles in the chart above a given threshold
var allCircles = chart.marks.wrap.filter(d=>d.type=='points').selectAll("g.point").select("circle")
allCircles.attr("fill", d=>d.x > config.threshold ? "black", null)
//do stuff when the sites marks are clicked
chart.marks.find(d=>d.id="sites").items.on("click, ...)