Published
Edited
Mar 27, 2020
Insert cell
md`# markers`
Insert cell
function returnLabel (d) { return d.label }
Insert cell
function removeExistingMarkers (svg) {
svg.selectAll('.mg-markers').remove()
svg.selectAll('.mg-baselines').remove()
}
Insert cell
function inRange(args) {
return function(d) {
return (
args.scales.X(d[args.xAccessor]) >= getPlotLeft(args) &&
args.scales.X(d[args.xAccessor]) <= getPlotRight(args)
);
};
}
Insert cell
function xPosition (args) {
return function (d) {
return args.scales.X(d[args.xAccessor])
}
}
Insert cell
function xPositionFixed (args) {
return d => xPosition(args).toFixed(2)
}
Insert cell
function yPositionFixed (args) {
return d => args.scales.Y(d.value).toFixed(2)
}
Insert cell
function placeAnnotations (checker, className, args, svg, lineFunction, textFunction) {
if (!checker) return
const g = svg.append('g').attr('class', className)
lineFunction(g, args)
textFunction(g, args)
}
Insert cell
function placeMarkers(args, svg) {
placeAnnotations(
args.markers,
'mg-markers',
args,
svg,
placeMarkerLines,
placeMarkerText
);
}
Insert cell
function placeBaselines(args, svg) {
placeAnnotations(
args.baselines,
'mg-baselines',
args,
svg,
placeBaselineLines,
placeBaselineText
);
}
Insert cell
function placeMarkerLines(gm, args) {
var xPosFixed = xPositionFixed(args);
gm.selectAll('.mg-markers')
.data(args.markers.filter(inRange(args)))
.enter()
.append('line')
.attr('x1', xPosFixed)
.attr('x2', xPosFixed)
.attr('y1', args.top)
.attr('y2', getPlotBottom(args))
.attr('class', function(d) {
return d.lineClass;
})
.attr('stroke-dasharray', '3,1');
}
Insert cell
function placeMarkerText(gm, args) {
gm.selectAll('.mg-markers')
.data(args.markers.filter(inRange(args)))
.enter()
.append('text')
.attr('class', function(d) {
return d.textClass || '';
})
.classed('mg-marker-text', true)
.attr('x', xPosition(args))
.attr(
'y',
args.xAxis_position === 'bottom'
? args.top * 0.95
: getBottom(args) + args.buffer
)
.attr('text-anchor', 'middle')
.text(returnLabel)
.each(function(d) {
if (d.click) {
select(this)
.style('cursor', 'pointer')
.on('click', d.click);
}
if (d.mouseover) {
select(this)
.style('cursor', 'pointer')
.on('mouseover', d.mouseover);
}
if (d.mouseout) {
select(this)
.style('cursor', 'pointer')
.on('mouseout', d.mouseout);
}
});

preventHorizontalOverlap(gm.selectAll('.mg-marker-text').nodes(), args);
}
Insert cell
function placeBaselineLines(gb, args) {
var yPos = yPositionFixed(args);
gb.selectAll('.mg-baselines')
.data(args.baselines)
.enter()
.append('line')
.attr('x1', getPlotLeft(args))
.attr('x2', getPlotRight(args))
.attr('y1', yPos)
.attr('y2', yPos);
}
Insert cell
function placeBaselineText(gb, args) {
var yPos = yPositionFixed(args);
gb.selectAll('.mg-baselines')
.data(args.baselines)
.enter()
.append('text')
.attr('x', getPlotRight(args))
.attr('y', yPos)
.attr('dy', -3)
.attr('text-anchor', 'end')
.text(returnLabel);
}
Insert cell
function markers(args) {
"use strict";

var svg = getSvgChildOf(args.target);
removeExistingMarkers(svg);
placeMarkers(args, svg);
placeBaselines(args, svg);
return this;
}
Insert cell
import {
getPlotLeft,
getPlotRight,
getPlotBottom,
getBottom,
preventHorizontalOverlap,
getSvgChildOf
} from '@neatlogic/utility'
Insert cell
select = require('d3-selection')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more