Skip to content

Commit d90d4e1

Browse files
authored
Merge pull request #1017 from plotly/range-plots
Range slider second iteration (part 2: on-par range plots !!!)
2 parents cb293c7 + c7de743 commit d90d4e1

12 files changed

+834
-245
lines changed

src/components/rangeslider/draw.js

+109-10
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ var d3 = require('d3');
1212

1313
var Plotly = require('../../plotly');
1414
var Plots = require('../../plots/plots');
15-
var Axes = require('../../plots/cartesian/axes');
15+
1616
var Lib = require('../../lib');
17+
var Drawing = require('../drawing');
18+
var Color = require('../color');
19+
20+
var Cartesian = require('../../plots/cartesian');
21+
var Axes = require('../../plots/cartesian/axes');
1722

1823
var dragElement = require('../dragelement');
1924
var setCursor = require('../../lib/setcursor');
2025

2126
var constants = require('./constants');
22-
var rangePlot = require('./range_plot');
2327

2428

2529
module.exports = function(gd) {
@@ -55,7 +59,14 @@ module.exports = function(gd) {
5559
.classed(constants.containerClassName, true)
5660
.attr('pointer-events', 'all');
5761

58-
rangeSliders.exit().remove();
62+
// remove exiting sliders and their corresponding clip paths
63+
rangeSliders.exit().each(function(axisOpts) {
64+
var rangeSlider = d3.select(this),
65+
opts = axisOpts[constants.name];
66+
67+
rangeSlider.remove();
68+
fullLayout._topdefs.select('#' + opts._clipId).remove();
69+
});
5970

6071
// remove push margin object(s)
6172
if(rangeSliders.exit().size()) clearPushMargins(gd);
@@ -82,6 +93,8 @@ module.exports = function(gd) {
8293
domain = axisOpts.domain;
8394

8495
opts._id = constants.name + axisOpts._id;
96+
opts._clipId = opts._id + '-' + fullLayout._uid;
97+
8598
opts._width = graphSize.w * (domain[1] - domain[0]);
8699
opts._height = (fullLayout.height - margin.b - margin.t) * opts.thickness;
87100
opts._offsetShift = Math.floor(opts.borderwidth / 2);
@@ -95,6 +108,7 @@ module.exports = function(gd) {
95108

96109
rangeSlider
97110
.call(drawBg, gd, axisOpts, opts)
111+
.call(addClipPath, gd, axisOpts, opts)
98112
.call(drawRangePlot, gd, axisOpts, opts)
99113
.call(drawMasks, gd, axisOpts, opts)
100114
.call(drawSlideBox, gd, axisOpts, opts)
@@ -279,17 +293,102 @@ function drawBg(rangeSlider, gd, axisOpts, opts) {
279293
});
280294
}
281295

282-
function drawRangePlot(rangeSlider, gd, axisOpts, opts) {
283-
var rangePlots = rangePlot(gd, opts._width, opts._height);
296+
function addClipPath(rangeSlider, gd, axisOpts, opts) {
297+
var fullLayout = gd._fullLayout;
284298

285-
var gRangePlot = rangeSlider.selectAll('g.' + constants.rangePlotClassName)
299+
var clipPath = fullLayout._topdefs.selectAll('#' + opts._clipId)
286300
.data([0]);
287301

288-
gRangePlot.enter().append('g')
289-
.classed(constants.rangePlotClassName, true);
302+
clipPath.enter().append('clipPath')
303+
.attr('id', opts._clipId)
304+
.append('rect')
305+
.attr({ x: 0, y: 0 });
306+
307+
clipPath.select('rect').attr({
308+
width: opts._width,
309+
height: opts._height
310+
});
311+
}
312+
313+
function drawRangePlot(rangeSlider, gd, axisOpts, opts) {
314+
var subplotData = Axes.getSubplots(gd, axisOpts),
315+
calcData = gd.calcdata;
316+
317+
var rangePlots = rangeSlider.selectAll('g.' + constants.rangePlotClassName)
318+
.data(subplotData, Lib.identity);
319+
320+
rangePlots.enter().append('g')
321+
.attr('class', function(id) { return constants.rangePlotClassName + ' ' + id; })
322+
.call(Drawing.setClipUrl, opts._clipId);
323+
324+
rangePlots.order();
325+
326+
rangePlots.exit().remove();
327+
328+
var mainplotinfo;
329+
330+
rangePlots.each(function(id, i) {
331+
var plotgroup = d3.select(this),
332+
isMainPlot = (i === 0);
333+
334+
var oppAxisOpts = Axes.getFromId(gd, id, 'y'),
335+
oppAxisName = oppAxisOpts._name;
336+
337+
var mockFigure = {
338+
data: [],
339+
layout: {
340+
xaxis: {
341+
domain: [0, 1],
342+
range: opts.range.slice()
343+
},
344+
width: opts._width,
345+
height: opts._height,
346+
margin: { t: 0, b: 0, l: 0, r: 0 }
347+
}
348+
};
349+
350+
mockFigure.layout[oppAxisName] = {
351+
domain: [0, 1],
352+
range: oppAxisOpts.range.slice()
353+
};
354+
355+
Plots.supplyDefaults(mockFigure);
356+
357+
var xa = mockFigure._fullLayout.xaxis,
358+
ya = mockFigure._fullLayout[oppAxisName];
359+
360+
var plotinfo = {
361+
id: id,
362+
plotgroup: plotgroup,
363+
xaxis: xa,
364+
yaxis: ya
365+
};
366+
367+
if(isMainPlot) mainplotinfo = plotinfo;
368+
else {
369+
plotinfo.mainplot = 'xy';
370+
plotinfo.mainplotinfo = mainplotinfo;
371+
}
372+
373+
Cartesian.rangePlot(gd, plotinfo, filterRangePlotCalcData(calcData, id));
374+
375+
if(isMainPlot) plotinfo.bg.call(Color.fill, opts.bgcolor);
376+
});
377+
}
378+
379+
function filterRangePlotCalcData(calcData, subplotId) {
380+
var out = [];
381+
382+
for(var i = 0; i < calcData.length; i++) {
383+
var calcTrace = calcData[i],
384+
trace = calcTrace[0].trace;
385+
386+
if(trace.xaxis + trace.yaxis === subplotId) {
387+
out.push(calcTrace);
388+
}
389+
}
290390

291-
gRangePlot.html(null);
292-
gRangePlot.node().appendChild(rangePlots);
391+
return out;
293392
}
294393

295394
function drawMasks(rangeSlider, gd, axisOpts, opts) {

src/components/rangeslider/helpers.js

-24
This file was deleted.

src/components/rangeslider/range_plot.js

-179
This file was deleted.

0 commit comments

Comments
 (0)