lucid-ui
Version:
A UI component library from Xandr.
451 lines • 20.4 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var d3Axis = __importStar(require("d3-axis"));
var d3Shape = __importStar(require("d3-shape"));
var d3Drag = __importStar(require("d3-drag"));
var d3Selection = __importStar(require("d3-selection"));
var d3Transition = __importStar(require("d3-transition"));
var react_dom_1 = __importDefault(require("react-dom"));
var d3Scale = __importStar(require("d3-scale"));
var lodash_1 = __importDefault(require("lodash"));
var d3Array = __importStar(require("d3-array"));
var style_helpers_1 = require("../../util/style-helpers");
var d3_helpers_1 = require("./d3-helpers");
var cx = style_helpers_1.lucidClassNames.bind('&-DraggableLineChart');
var getAttributes = function (selection, obj) {
return lodash_1.default.reduce(obj, function (acc, value) {
// @ts-ignore
acc[value] = selection.attr(value);
return acc;
}, {});
};
var DraggableLineChartD3 = /** @class */ (function () {
function DraggableLineChartD3(selection, params) {
var _this = this;
this.setMouseDown = function (isMouseDown, mouseDownStep) {
_this.params.isMouseDown = isMouseDown;
_this.params.mouseDownStep = mouseDownStep;
};
this.getIsMouseDown = function () {
return _this.params.isMouseDown;
};
this.getMouseDownStep = function () {
return _this.params.mouseDownStep || 0;
};
this.getHasRenderedPoint = function () {
return !!_this.params.hasRenderedPoint;
};
this.getHasRenderedLine = function () {
return !!_this.params.hasRenderedLine;
};
this.setHasRenderedPoint = function () {
_this.params.hasRenderedPoint = true;
};
this.setHasRenderedLine = function () {
_this.params.hasRenderedLine = true;
};
this.shouldShowPreselect = function () {
var hasUserValues = lodash_1.default.some(_this.params.data, function (_a) {
var y = _a.y;
return y > 0;
});
return !!_this.params.onPreselect && !hasUserValues;
};
this.drag = function () {
var _a = _this, xScale = _a.xScale, yScale = _a.yScale, renderLine = _a.renderLine, renderPoints = _a.renderPoints, selection = _a.selection;
var _b = _this.params, cx = _b.cx, onDragEnd = _b.onDragEnd;
var initialPosition;
return d3Drag
.drag()
.on('start', function () {
var activeDot = d3Selection.select(this);
initialPosition = Number(activeDot.attr('cy'));
})
.on('drag', function (pointData) {
var _a = yScale.range(), max = _a[0], min = _a[1];
var activeDot = d3Selection.select(this);
// @ts-ignore
var adjMouseY = initialPosition + d3Selection.event.y;
var newPointY = adjMouseY < min ? min : adjMouseY > max ? max : adjMouseY;
var lines = selection.selectAll("path.".concat(cx('&-Line')));
pointData.y = Number(yScale.invert(newPointY));
activeDot.attr('cy', newPointY);
var line = d3Shape
.line()
.x(function (chartData) { return xScale(chartData.x) || 0; })
.y(function (chartData) { return yScale(chartData.y); });
lines.attr('d', line);
})
.on('end', function (d) {
if (onDragEnd)
onDragEnd(d.y, d.x);
renderLine();
renderPoints();
});
};
this.renderXAxis = function () {
var _a = _this.params, margin = _a.margin, height = _a.height, xAxisTicksVertical = _a.xAxisTicksVertical, dataIsCentered = _a.dataIsCentered, cx = _a.cx, xAxisRenderProp = _a.xAxisRenderProp, data = _a.data;
var xGroup = (0, d3_helpers_1.getGroup)(_this.selection, "".concat(cx('&-Axis')));
xGroup
.call(function (xAxis) {
xAxis
.attr('transform', "translate(".concat(0, ",").concat(margin.top, ")"))
.call(d3_helpers_1.lucidXAxis, {
xScale: _this.xScale,
tickSize: margin.top + margin.bottom - height,
xAxisRenderProp: xAxisRenderProp,
dataIsCentered: dataIsCentered,
data: data,
});
if (xAxisTicksVertical) {
xAxis.classed('Vert', true);
}
else {
xAxis.classed('NoVert', true);
}
if (dataIsCentered) {
xAxis.classed('Center', true);
}
})
.call(function () { return xGroup; });
};
this.renderYAxis = function () {
var yGroup = (0, d3_helpers_1.getGroup)(_this.selection, 'yAxisGroup');
yGroup
.call(function (yAxis) {
var _a = _this.params, margin = _a.margin, cx = _a.cx, yAxisFormatter = _a.yAxisFormatter;
yAxis
.attr('transform', "translate(".concat(margin.left, ",").concat(0, ")"))
.classed("".concat(cx('&-Axis')), true)
.transition()
.duration(500)
.call(d3Axis
.axisLeft(_this.yScale)
.tickFormat(yAxisFormatter));
})
.call(function () { return yGroup; });
};
this.renderLine = function () {
if (_this.shouldShowPreselect()) {
return;
}
var _a = _this.params, dataIsCentered = _a.dataIsCentered, cx = _a.cx;
if (!_this.getHasRenderedLine()) {
if (dataIsCentered) {
var innerXTickWidth = _this.xScale.step();
_this.selection
.append('g')
.append('path')
.attr('class', "".concat(cx('&-Line')))
.attr('transform', "translate(".concat(innerXTickWidth / 2, ", 0)"));
}
else {
_this.selection
.append('g')
.append('path')
.attr('class', "".concat(cx('&-Line')));
}
_this.setHasRenderedLine();
}
var lines = _this.selection.selectAll("path.".concat(cx('&-Line')));
lines.datum(_this.params.data).enter();
lines
.transition(d3Transition.transition().duration(100))
.attr('fill', 'none')
.attr('d', d3Shape
.line()
.x(function (d) { return _this.xScale(d.x) || 0; })
.y(function (d) { return _this.yScale(d.y); }));
};
this.renderEmptyRenderProp = function (height, width) {
var emptyRenderProp = _this.params.emptyRenderProp;
if (!emptyRenderProp || !_this.shouldShowPreselect()) {
return;
}
var emptyDataObject = _this.selection.selectAll('.emptyRender');
if (emptyDataObject.empty()) {
var emptyRender = _this.selection
.selectAll('.overlayContainer')
.append('foreignObject')
.attr('height', height)
.attr('width', width)
.attr('x', _this.params.margin.left)
.classed('emptyRender', true);
emptyRender.html(function (value, num, node) {
react_dom_1.default.render(emptyRenderProp(), node[0]);
});
}
};
this.renderPoints = function () {
if (_this.shouldShowPreselect()) {
return;
}
var _a = _this.params, data = _a.data, dataIsCentered = _a.dataIsCentered;
var circle = _this.getHasRenderedPoint()
? _this.selection.selectAll('circle').data(data).join('circle')
: _this.selection
.append('g')
.selectAll('circle')
.data(data)
.join('circle');
if (dataIsCentered) {
var innerXTickWidth = _this.xScale.step();
circle
// @ts-ignore
.transition()
.duration(100)
.attr('cx', function (d) { return _this.xScale(d.x) || 0; })
.attr('cy', function (d) { return _this.yScale(d.y); })
.attr('r', 5)
.attr('transform', "translate(".concat(innerXTickWidth / 2, ", 0)"))
.style('fill', '#587EBA')
.style('stroke', 'white')
.style('stroke-width', 1);
}
else {
circle
// @ts-ignore
.transition()
.duration(100)
.attr('cx', function (d) { return _this.xScale(d.x) || 0; })
.attr('cy', function (d) { return _this.yScale(d.y); })
.attr('r', 5)
.style('fill', '#587EBA')
.style('stroke', 'white')
.style('stroke-width', 1);
}
if (!_this.getHasRenderedPoint())
circle.call(_this.drag());
_this.setHasRenderedPoint();
};
this.reRenderDragBox = function (_a) {
var dragBox = _a.dragBox, mouseX = _a.mouseX, xLeft = _a.xLeft, xRight = _a.xRight, stepWidth = _a.stepWidth, stepCount = _a.stepCount;
var isLeft = xLeft >= mouseX;
var isRight = xRight <= mouseX;
var mouseDownStep = _this.getMouseDownStep();
if (isLeft) {
var difference = lodash_1.default.max([xLeft - mouseX, 0]) || 0;
var rawStepsSelected = Math.floor(difference / stepWidth) + 2;
var maxStepsAvailable = mouseDownStep + 1;
var stepsSelected = lodash_1.default.min([rawStepsSelected, maxStepsAvailable]) || 1;
var activeBoxWidth = stepsSelected * stepWidth;
var nextXLeft = xRight - activeBoxWidth;
dragBox.attr('x', nextXLeft);
dragBox.attr('width', activeBoxWidth);
}
else if (isRight) {
var difference = lodash_1.default.max([mouseX - xRight, 0]) || 0;
var rawStepsSelected = Math.floor(difference / stepWidth) + 2;
var maxStepsAvailable = stepCount - mouseDownStep;
var stepsSelected = lodash_1.default.min([rawStepsSelected, maxStepsAvailable]) || 1;
var activeBoxWidth = stepsSelected * stepWidth;
dragBox.attr('x', xLeft);
dragBox.attr('width', activeBoxWidth);
}
else {
dragBox.attr('x', xLeft);
dragBox.attr('width', stepWidth);
}
};
this.renderHoverTracker = function () {
var _a = _this.params, height = _a.height, _b = _a.margin, top = _b.top, bottom = _b.bottom, data = _a.data, onPreselect = _a.onPreselect;
var _c = _this, shouldShowPreselect = _c.shouldShowPreselect, setMouseDown = _c.setMouseDown, getIsMouseDown = _c.getIsMouseDown, getMouseDownStep = _c.getMouseDownStep, reRenderDragBox = _c.reRenderDragBox, xScale = _c.xScale, selection = _c.selection;
if (!shouldShowPreselect()) {
selection.selectAll('.overlayContainer').remove();
return;
}
var innerHeight = height - top - bottom;
var stepWidth = xScale.step();
var stepCount = data.length;
var overlayContainer = selection
.append('g')
.classed('overlayContainer', true)
.attr('transform', "translate(".concat(0, ",").concat(top, ")"));
_this.renderEmptyRenderProp(innerHeight, stepCount * stepWidth);
var overlayTrack = overlayContainer.selectAll('rect').data(data).enter();
overlayTrack
.append('rect')
.attr('x', function (chartData) { return _this.xScale(chartData.x) || 0; })
.attr('y', 0)
.attr('width', function (chartData) { return _this.xScale.step(); })
.attr('height', innerHeight)
.classed(cx('&-overlayTrack'), true)
// @ts-ignore
.on('mouseenter', function (d, i, nodes) {
if (!getIsMouseDown()) {
d3Selection.select(nodes[i]).classed('active', true);
}
})
// @ts-ignore
.on('mouseout', function (d, i, nodes) {
if (!getIsMouseDown()) {
d3Selection.select(nodes[i]).classed('active', false);
}
})
.on('mousedown', function (d, i) {
d3Selection.selectAll('.active').classed('active', false);
var currentTarget = d3Selection.select(this);
var _a = getAttributes(currentTarget, [
'x',
'y',
'width',
'height',
]), x = _a.x, y = _a.y, width = _a.width, height = _a.height;
// @ts-ignore
setMouseDown(true, i);
var xLeft = +x;
var xRight = +x + +width;
// @ts-ignore
var container = d3Selection.select(this.parentNode);
container
.append('rect')
.attr('x', x)
.attr('y', y)
.attr('width', width)
.attr('height', height)
.classed(cx('&-overlayTrack'), true)
.classed('active', true)
.classed('dragBox', true)
.on('mouseout', function () {
// @ts-ignore
var mouseX = d3Selection.mouse(this)[0];
var dragBox = selection.selectAll('.dragBox');
reRenderDragBox({
dragBox: dragBox,
mouseX: mouseX,
xLeft: xLeft,
xRight: xRight,
stepWidth: stepWidth,
stepCount: stepCount,
});
})
.on('mousemove', function () {
// @ts-ignore
var mouseX = d3Selection.mouse(this)[0];
var dragBox = selection.selectAll('.dragBox');
reRenderDragBox({
dragBox: dragBox,
mouseX: mouseX,
xLeft: xLeft,
xRight: xRight,
stepWidth: stepWidth,
stepCount: stepCount,
});
})
.on('mouseup', function () {
var clickStep = getMouseDownStep();
var activeBox = selection.selectAll('.dragBox');
var _a = getAttributes(activeBox, ['x', 'width']), x = _a.x, width = _a.width;
var isRight = xLeft === +x;
var steps = Math.round(+width / stepWidth);
var startingIndex = isRight ? clickStep : clickStep - steps + 1;
var endingIndex = startingIndex + steps - 1;
var updatedData = data.map(function (step, i) { return (__assign(__assign({}, step), { isSelected: i >= startingIndex && i <= endingIndex })); });
!!onPreselect && onPreselect(updatedData);
setMouseDown(false);
selection.selectAll('.dragBox').remove();
selection.selectAll('.overlayContainer').remove();
});
});
};
this.renderLineChart = function () {
_this.renderXAxis();
_this.renderYAxis();
_this.renderHoverTracker();
_this.renderLine();
_this.renderPoints();
};
this.updateLineChart = function (data) {
_this.params.data = data;
_this.yScale.domain([
lodash_1.default.isUndefined(_this.params.yAxisMin)
? d3Array.min(_this.params.data, function (d) { return d.y; })
: _this.params.yAxisMin,
d3Array.max(_this.params.data, function (d) { return d.y; }) || 10,
]);
_this.renderLineChart();
};
this.selection = selection;
this.params = params;
if (params.dataIsCentered) {
this.xScale = d3Scale
.scalePoint()
.domain(__spreadArray(__spreadArray([], this.params.data.map(function (d) { return d.x; }), true), [''], false))
.range([
this.params.margin.left,
this.params.width -
this.params.margin.right -
this.params.margin.left,
]);
}
else {
this.xScale = d3Scale
.scalePoint()
.domain(this.params.data.map(function (d) { return d.x; }))
.range([
this.params.margin.left,
this.params.width -
this.params.margin.right -
this.params.margin.left,
]);
}
this.yScale = d3Scale
.scaleLinear()
.domain([
lodash_1.default.isUndefined(this.params.yAxisMin)
? d3Array.min(this.params.data, function (d) { return d.y; })
: this.params.yAxisMin,
d3Array.max(this.params.data, function (d) { return d.y; }) || 10,
])
.nice()
.range([
this.params.height - this.params.margin.bottom,
this.params.margin.top,
]);
}
return DraggableLineChartD3;
}());
exports.default = DraggableLineChartD3;
//# sourceMappingURL=DraggableLineChartD3.js.map