@redsift/d3-rs-lines
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -11,4 +11,3 @@ 'use strict'; | ||
var del = require('del'); | ||
var util = require('gulp-util'); | ||
var rollup = require('rollup-stream'); | ||
var rollup = require('rollup-stream'); | ||
var uglify = require('gulp-uglify'); | ||
@@ -57,12 +56,12 @@ var browserSync = require('browser-sync').create(); | ||
gulp.task('umd', task.umd = () => { | ||
gulp.task('umd', task.umd = () => { | ||
return rollup({ | ||
name: outputFilename.replace(/-/g, '_'), | ||
globals: globalMap, | ||
input: 'index.js', | ||
entry: 'index.js', | ||
format: 'umd', | ||
sourcemap: true, | ||
plugins: [ | ||
plugins: [ | ||
json({ | ||
include: [ '**/package.json' , 'node_modules/**/*.json' ], | ||
include: [ '**/package.json' , 'node_modules/**/*.json' ], | ||
exclude: [ ] | ||
@@ -88,5 +87,5 @@ }), | ||
}), | ||
commonjs(), | ||
buble() | ||
] | ||
commonjs(), | ||
buble() | ||
] | ||
}) | ||
@@ -114,10 +113,10 @@ .pipe(source('main.js', './src')) | ||
gulp.task('serve', ['default', 'browser-sync'], function() { | ||
gulp.task('build', gulp.series([ 'clean' ], task.umd)); | ||
gulp.task('default', gulp.series([ 'umd' ])); | ||
gulp.task('serve', gulp.series(['default', 'browser-sync'], function() { | ||
gulp.watch(['./*.js', './src/*.js'], [ 'umd' ]); | ||
gulp.watch('./distribution/*.js').on('change', () => browserSync.reload('*.js')); | ||
gulp.watch('./examples/**/*.html').on('change', () => browserSync.reload('*.html')); | ||
}); | ||
gulp.task('build', [ 'clean' ], task.umd); | ||
gulp.task('default', [ 'umd' ]); | ||
})); |
{ | ||
"name": "@redsift/d3-rs-lines", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "Generates line charts using D3v4.", | ||
@@ -17,7 +17,5 @@ "keywords": [ | ||
}, | ||
"module": "dist/d3-rs-lines.esm.js", | ||
"jsnext:main": "dist/d3-rs-lines.esm.js", | ||
"main": "dist/d3-rs-lines.umd.min.js", | ||
"browser": "dist/d3-rs-lines.umd.min.js", | ||
"esnext": "src/index.js", | ||
"main": "distribution/d3-rs-lines.umd-es2015.js", | ||
"browser": "distribution/d3-rs-lines.umd-es2015.min.js", | ||
"jsnext:main": "index.js", | ||
"repository": { | ||
@@ -37,7 +35,7 @@ "type": "git", | ||
"dependencies": { | ||
"@redsift/d3-rs-intl": "^0.1.0", | ||
"@redsift/d3-rs-legends": "^0.2.0", | ||
"@redsift/d3-rs-svg": "^0.5.2", | ||
"@redsift/d3-rs-theme": "^0.4.2", | ||
"@redsift/d3-rs-tip": "^0.6.0", | ||
"@redsift/d3-rs-intl": "0.3.0", | ||
"@redsift/d3-rs-legends": "0.4.0", | ||
"@redsift/d3-rs-svg": "0.7.0", | ||
"@redsift/d3-rs-theme": "0.6.0", | ||
"@redsift/d3-rs-tip": "0.10.0", | ||
"d3-array": "^1.0.1", | ||
@@ -55,24 +53,21 @@ "d3-axis": "^1.0.3", | ||
"devDependencies": { | ||
"@redsift/rollup-bundler": "^0.5.1", | ||
"@redsift/tape-reel": "^0.1.0", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
"babel-preset-env": "^1.6.1", | ||
"@redsift/rollup-bundler": "^2.0.2", | ||
"@redsift/tape-reel": "~0.1.1", | ||
"browser-sync": "^2.14.0", | ||
"del": "^2.2.2", | ||
"eslint": "^3.3.1", | ||
"gulp": "^3.9.1", | ||
"gulp-rename": "^1.2.2", | ||
"gulp": "^4.0.2", | ||
"gulp-rename": "^1.4.0", | ||
"gulp-sourcemaps": "^2.0.0-alpha", | ||
"gulp-uglify": "^2.0.0", | ||
"gulp-util": "^3.0.7", | ||
"rollup": "^0.34.10", | ||
"rollup-plugin-buble": "^0.13.0", | ||
"rollup-plugin-commonjs": "^3.3.0", | ||
"rollup-plugin-json": "^2.0.0", | ||
"rollup-plugin-node-resolve": "^2.0.0", | ||
"rollup-stream": "^1.11.0", | ||
"vinyl-buffer": "^1.0.0", | ||
"vinyl-source-stream": "^1.1.0", | ||
"gulp-uglify": "^3.0.2", | ||
"vinyl-buffer": "^1.0.1", | ||
"vinyl-source-stream": "^2.0.0", | ||
"yargs": "^5.0.0" | ||
}, | ||
"overrides": { | ||
"lodash": "4.17.21", | ||
"lodash.template": "4.5.0", | ||
"chokidar": "3.5.3", | ||
"glob-parent": "6.0.2" | ||
} | ||
} |
@@ -99,3 +99,5 @@ # d3-rs-lines | ||
`onClick`|*Function* Handler for a click event on a data series. |N | Examples: [CodePen](http://codepen.io/geervesh/pen/NRrEkq) | ||
`legendSize`|*Number* Height of the legend component (if present) |N | ||
`legendIsToggleable`|*Boolean* If true, the legend's items will have a checkbox that make it able to switch on/off data sets.|N | ||
`tintColor`|*String* Color of some components, only supports checkbox color for now|N | ||
### Time | ||
@@ -102,0 +104,0 @@ |
536
src/lines.js
@@ -60,3 +60,2 @@ | ||
curveBasis, | ||
//curveBundle, | ||
curveCardinal, | ||
@@ -292,3 +291,2 @@ curveCatmullRom, | ||
stacked = null, | ||
onClick = null, | ||
stackOrder = stackOrderNone, | ||
@@ -312,2 +310,6 @@ stackOffset = stackOffsetNone, | ||
legend = [ ], | ||
legendsEnabled = [ ], | ||
legendIsToggleable = false, | ||
legendSize = 14, // default legend size (from d3-rs-legends) | ||
tintColor = '#000', | ||
fill = null, | ||
@@ -507,16 +509,39 @@ labelTime = null, | ||
let data = g.datum() || []; | ||
let _mapData = function(option, arr = data) { | ||
if (!Array.isArray(option)) { | ||
return arr.map(d => option === true ? | ||
trim == null ? d : d.slice(0, trim) | ||
: []); | ||
} else { | ||
return arr.map(function (d, i) { | ||
if (i < option.length) { | ||
return option[i] === true ? | ||
trim == null ? d : d.slice(0, trim) | ||
: []; | ||
} | ||
return []; | ||
}); | ||
} | ||
} | ||
if (!Array.isArray(data)) { | ||
data = [ data ]; | ||
} | ||
if (data.length > 0) { | ||
let _data = data.map(item => Object.assign( | ||
{}, | ||
item, | ||
{v: item.v.map((v, idx) => legendsEnabled.includes(idx) ? v : null)} | ||
) | ||
); | ||
if (_data.length > 0) { | ||
if (stacked !== null && stacked !== false) { | ||
let stacker = stack(); | ||
if (stacked === true) { | ||
let maxD = max(data, d => d.v.length); | ||
let maxD = max(_data, d => d.v.length); | ||
stacker.keys(Array.from(Array(maxD).keys())).value((d,k) => d.v[k] != null ? d.v[k] : 0); | ||
@@ -526,45 +551,26 @@ } else { | ||
} | ||
let _stackOrder = _mapStackOrder(stackOrder); | ||
if (_stackOrder != null) stacker.order(_stackOrder); | ||
let _stackOffset = _mapStackOffset(stackOffset); | ||
if (_stackOffset != null) stacker.offset(_stackOffset); | ||
data = stacker(data).map(s => s.map(v => [ v.data.l, v ])); | ||
} else if (Array.isArray(data[0])) { | ||
data = data.map(a => a.map((d, i) => value(d, i, true))).map(s => s.map(e => [ e[0], [ 0, e[1] ] ]) ); | ||
_data = stacker(_data).map(s => s.map(v => [ v.data.l, v ])); | ||
} else if (Array.isArray(_data[0])) { | ||
_data = _data.map(a => a.map((d, i) => value(d, i, true))).map(s => s.map(e => [ e[0], [ 0, e[1] ] ]) ); | ||
} else { | ||
data = _flatArrays(data.map((d, i) => value(d, i, false))).map(s => s.map(e => [ e[0], [ 0, e[1] ] ]) ); | ||
_data = _flatArrays(_data.map((d, i) => value(d, i, false))).map(s => s.map(e => [ e[0], [ 0, e[1] ] ]) ); | ||
} | ||
} | ||
let _mapData = function(option) { | ||
let out = []; | ||
if (!Array.isArray(option)) { | ||
out = data.map(d => option === true ? | ||
trim == null ? d : d.slice(0, trim) | ||
: []); | ||
} else { | ||
out = data.map(function (d, i) { | ||
if (i < option.length) { | ||
return option[i] === true ? | ||
trim == null ? d : d.slice(0, trim) | ||
: []; | ||
} | ||
return []; | ||
}); | ||
} | ||
return out; | ||
} | ||
let fdata = _mapData(_fillArea); | ||
let sdata = _mapData(_fillStroke); | ||
let _curve = data.map(function (d, i) { | ||
let fdata = _mapData(_fillArea, _data); | ||
let sdata = _mapData(_fillStroke, _data); | ||
let _curve = _data.map(function (d, i) { | ||
if (!Array.isArray(curve)) { | ||
return _mapCurve(curve); | ||
} | ||
} | ||
if (i < curve.length) { | ||
@@ -576,7 +582,7 @@ return _mapCurve(curve[i]); | ||
g.datum(data); // this rebind is required even though there is a following select | ||
g.datum(_data); // this rebind is required even though there is a following select | ||
let minV = minValue; | ||
if (minV == null) { | ||
minV = min(data, d => min(d, d1 => min(d1[1]) )); | ||
minV = min(_data, d => min(d, d1 => min(d1[1]) )); | ||
if (minV > 0) { | ||
@@ -588,25 +594,25 @@ minV = logValue === 0 ? 0 : 1; | ||
} | ||
let maxV = maxValue; | ||
if (maxV == null) { | ||
maxV = max(data, d => max(d, d1 => max(d1[1]) )); | ||
maxV = max(_data, d => max(d, d1 => max(d1[1]) )); | ||
} | ||
let minI = minIndex; | ||
if (minI == null) { | ||
minI = min(data, d => min(d, d1 => d1[0])); | ||
minI = min(_data, d => min(d, d1 => d1[0])); | ||
} | ||
if (minI == null) minI = 0; | ||
let maxI = maxIndex; | ||
if (maxI == null) { | ||
maxI = max(data, d => max(d, d1 => d1[0])); | ||
maxI = max(_data, d => max(d, d1 => d1[0])); | ||
} | ||
if (maxI == null) maxI = DEFAULT_SCALE; | ||
let w = root.childWidth(), | ||
h = root.childHeight(); | ||
let colors = _makeFillFn(); | ||
// Create the legend | ||
@@ -617,18 +623,35 @@ let lchart = null; | ||
if (id) lid = `legend-${id}`; | ||
lchart = legends(lid).width(w).height(h).style(null).margin(0).inset(0).fill(colors).theme(theme).orientation(legendOrientation); | ||
lchart = legends(lid) | ||
.width(w) | ||
.height(h) | ||
.style(null) | ||
.margin(0) | ||
.inset(0) | ||
.fill(colors) | ||
.theme(theme) | ||
.orientation(legendOrientation) | ||
.legendSize(legendSize) | ||
.toggleable(legendIsToggleable) | ||
.onEnabledLegendItemsChange(enabledLegendItems => { | ||
legendsEnabled = enabledLegendItems; | ||
const event = document.createEvent('HTMLEvents'); | ||
event.initEvent('resize', true, false); | ||
node._groups[0][0].dispatchEvent(event); | ||
}) | ||
.tintColor(tintColor) | ||
; | ||
_inset = lchart.childInset(_inset); | ||
elmS.datum(legend).call(lchart); | ||
} | ||
elmS.datum(legend).call(lchart); | ||
} | ||
// margin is a bit of a hack but don't trim the top | ||
let marginTop = margin.top !== undefined ? margin.top : margin; | ||
g.select('#' + cid).select('rect') | ||
.attr('x', _inset.left) | ||
.attr('y', -(_inset.top + marginTop)) | ||
.attr('width', w - _inset.right - _inset.left) | ||
.attr('height', h - _inset.bottom + _inset.top + marginTop); | ||
let sV = scaleLinear(); | ||
.attr('x', _inset.left) | ||
.attr('y', -(_inset.top + marginTop)) | ||
.attr('width', w - _inset.right - _inset.left) | ||
.attr('height', h - _inset.bottom + _inset.top + marginTop); | ||
let sV = scaleLinear(); | ||
if (logValue > 0) sV = scaleLog().base(logValue); | ||
@@ -639,4 +662,4 @@ let scaleV = sV.domain([ minV, maxV ]).range([ h - _inset.bottom, _inset.top ]); | ||
} | ||
let sI = scaleLinear(); | ||
let sI = scaleLinear(); | ||
if (labelTime != null) sI = scaleTime(); | ||
@@ -652,9 +675,9 @@ let domainI = [ minI, maxI ]; | ||
formatValue = '.0r'; | ||
} | ||
} | ||
let axis = (axisValue === 'left') ? axisLeft : axisRight; | ||
let aV = axis(scaleV) | ||
.tickPadding(axisPaddingValue) | ||
.ticks(tickCountValue, (formatValue == null ? scaleV.tickFormat(tickCountValue) : formatValue)); | ||
.tickPadding(axisPaddingValue) | ||
.ticks(tickCountValue, (formatValue == null ? scaleV.tickFormat(tickCountValue) : formatValue)); | ||
if (gridValue === true) { | ||
@@ -668,3 +691,3 @@ aV.tickSizeInner((_inset.left + _inset.right) - w); | ||
} | ||
let aVMinor = null; | ||
@@ -676,8 +699,8 @@ if (tickMinorValue !== null) { | ||
let gAxisV = g.select('g.axis-v') | ||
.attr('transform', 'translate(' + axisTranslate + ',0)'); | ||
.attr('transform', 'translate(' + axisTranslate + ',0)'); | ||
let gAxisVMinor = g.select('g.axis-v-minor') | ||
.attr('transform', 'translate(' + axisTranslate + ',0)'); | ||
.attr('transform', 'translate(' + axisTranslate + ',0)'); | ||
let aI = axisBottom(scaleI).tickPadding(axisPaddingIndex); | ||
if (labelTime != null) { | ||
@@ -689,9 +712,9 @@ let freq = _mapIntervalTickCount(tickCountIndex); | ||
if (typeof labelTime === 'function') { | ||
aI.tickFormat(labelTime); | ||
aI.tickFormat(labelTime); | ||
} else if (labelTime === 'multi') { | ||
aI.tickFormat(timeMultiFormat()); | ||
aI.tickFormat(timeMultiFormat()); | ||
} else if (labelTime === 'multi-local') { | ||
aI.tickFormat(timeMultiFormat({ localtime: true })); | ||
aI.tickFormat(timeMultiFormat({ localtime: true })); | ||
} else { | ||
aI.tickFormat(timeFormat(labelTime)); | ||
aI.tickFormat(timeFormat(labelTime)); | ||
} | ||
@@ -705,7 +728,7 @@ } else { | ||
aI.tickSizeInner(DEFAULT_MAJOR_TICK_SIZE); | ||
} | ||
} | ||
if (tickDisplayIndex != null) { | ||
aI.tickFormat(tickDisplayIndex); | ||
} | ||
} | ||
let aIMinor = null; | ||
@@ -719,9 +742,9 @@ if (tickMinorIndex !== null) { | ||
} | ||
let gAxisI = g.select('g.axis-i') | ||
.attr('transform', 'translate(0,' + (h - _inset.bottom) + ')'); | ||
.attr('transform', 'translate(0,' + (h - _inset.bottom) + ')'); | ||
let gAxisIMinor = g.select('g.axis-i-minor') | ||
.attr('transform', 'translate(0,' + (h - _inset.bottom) + ')'); | ||
.attr('transform', 'translate(0,' + (h - _inset.bottom) + ')'); | ||
if (transition === true && animateAxis === true) { | ||
@@ -732,30 +755,30 @@ gAxisVMinor = gAxisVMinor.transition(context); | ||
gAxisI = gAxisI.transition(context); | ||
} | ||
} | ||
if (aIMinor !== null) { | ||
gAxisIMinor.call(aIMinor); | ||
gAxisIMinor.call(aIMinor); | ||
} else { | ||
gAxisIMinor.selectAll('*').remove(); | ||
} | ||
if (aVMinor !== null) { | ||
gAxisVMinor.call(aVMinor); | ||
gAxisVMinor.call(aVMinor); | ||
} else { | ||
gAxisVMinor.selectAll('*').remove(); | ||
} | ||
gAxisV.call(aV) | ||
.selectAll('line') | ||
.attr('class', (d, i) => gridValue ? i === 0 ? 'grid first' : 'grid' : null); | ||
.selectAll('line') | ||
.attr('class', (d, i) => gridValue ? i === 0 ? 'grid first' : 'grid' : null); | ||
gAxisI.call(aI) | ||
.selectAll('line') | ||
.selectAll('line') | ||
.attr('class', (d, i) => gridIndex ? i === 0 ? 'grid first' : 'grid' : null); | ||
const safeScaleV = (v) => (logValue > 0 && v < 1) ? scaleV.range()[0] : scaleV(v); | ||
// Note: A lot of scaleI, scaleV calls. | ||
// Note: A lot of scaleI, scaleV calls. | ||
let lines = line() | ||
.x(d => scaleI(d[0])) | ||
.y(d => safeScaleV(d[1][1])); | ||
.x(d => scaleI(d[0])) | ||
.y(d => safeScaleV(d[1][1])); | ||
// These can be truncated .defined(d => scaleI(d[0]) <= (w - _inset.right) && scaleV(d[1][1]) >= _inset.top); | ||
@@ -767,10 +790,10 @@ | ||
.y1(d => safeScaleV(d[1][1]) ); // top | ||
let uS = psymbol.map(_mapSymbols).map(s => s != null ? symbol().type(s).size(symbolSize) : null); | ||
let sym = data.map((d, i) => i < uS.length ? uS[i] : null).map(d => d !== null ? d : null); | ||
let sym = _data.map((d, i) => i < uS.length ? uS[i] : null).map(d => d !== null ? d : null); | ||
let elmL = g.select('g.lines'); | ||
let elmG = elmL.selectAll('g.line').data(data); | ||
let elmG = elmL.selectAll('g.line').data(_data); | ||
elmG.exit().remove(); | ||
@@ -782,15 +805,15 @@ let elmGNew = elmG.enter().append('g').attr('class', 'line'); | ||
elmG = elmG.merge(elmGNew); | ||
let elmArea = elmL.selectAll('path.area').data(fdata); | ||
let elmStroke = elmL.selectAll('path.stroke').data(sdata); | ||
// Add the clipping paths to ensure curves do not move outside | ||
// Add the clipping paths to ensure curves do not move outside | ||
// the graph area. Do this before the animation | ||
elmArea.attr('clip-path', `url(#${cid})`); | ||
elmStroke.attr('clip-path', `url(#${cid})`); | ||
if (transition === true) { | ||
elmArea = elmArea.transition(context); | ||
elmStroke = elmStroke.transition(context); | ||
} | ||
} | ||
@@ -801,6 +824,6 @@ function revealInterpolation(tr, fn) { | ||
if (tr == null) tr = 1; | ||
let interpolate = scaleLinear() | ||
.domain([0, 1]) | ||
.range([tr, d.length + 1]); | ||
.domain([0, 1]) | ||
.range([tr, d.length + 1]); | ||
@@ -811,3 +834,3 @@ return function(t) { | ||
let flooredX = Math.floor(interpolate(t)); | ||
let weight = interpolate(t) - flooredX; | ||
@@ -827,5 +850,5 @@ let interpolatedLine = d.slice(0, flooredX); | ||
} | ||
} | ||
} | ||
} | ||
function valueInterpolation(tr, fn) { | ||
@@ -838,3 +861,3 @@ return function (d, i) { | ||
if (flooredX < 0) return ''; | ||
let interpolatedLine = d.slice(0, flooredX); | ||
@@ -849,11 +872,11 @@ | ||
} | ||
} | ||
} | ||
} | ||
} | ||
elmArea.attr('opacity', _fillOpacity) | ||
.attr('fill', (d,i) => colors(d, i, 'area')); | ||
.attr('fill', (d,i) => colors(d, i, 'area')); | ||
elmStroke.attr('stroke', (d,i) => colors(d, i, 'stroke')); | ||
let interpolation = null; | ||
@@ -867,3 +890,3 @@ if (transition === true) { | ||
} | ||
if (interpolation !== null) { | ||
@@ -876,3 +899,3 @@ elmArea.attrTween('d', interpolation(_ptrim, i => _curve[i] != null ? areas.curve(_curve[i]) : areas)); | ||
} | ||
let eS = elmG.select('g.symbols').selectAll('path').data((d, i) => sym[i] != null ? d.map(function (v) { return { v : v, i : i }; }) : []); | ||
@@ -882,20 +905,20 @@ eS.exit().remove(); | ||
eS.attr('transform', d => 'translate('+scaleI(d.v[0])+','+safeScaleV(d.v[1][1])+')') | ||
.attr('d', (d) => sym[d.i](d.v, d.i)) | ||
.attr('fill', d => colors(d.v, d.i, 'symbol')) | ||
.attr('stroke', 'none'); | ||
let flat = data.reduce((p, a, s) => p.concat(a.map((e, i) => [ e[0], e[1][1], s, i, (e[1][1] - e[1][0])] )), []); | ||
.attr('d', (d) => sym[d.i](d.v, d.i)) | ||
.attr('fill', d => colors(d.v, d.i, 'symbol')) | ||
.attr('stroke', 'none'); | ||
let flat = _data.reduce((p, a, s) => p.concat(a.map((e, i) => [ e[0], e[1][1], s, i, (e[1][1] - e[1][0])] )), []); | ||
let overlay = voronoi() | ||
.x(d => scaleI(d[0])) | ||
.y(d => safeScaleV(d[1])) | ||
.extent([ [ _inset.left, _inset.top ], [ w - _inset.right, h - _inset.bottom ] ]) | ||
.polygons(flat); | ||
.x(d => scaleI(d[0])) | ||
.y(d => safeScaleV(d[1])) | ||
.extent([ [ _inset.left, _inset.top ], [ w - _inset.right, h - _inset.bottom ] ]) | ||
.polygons(flat); | ||
let vmesh = g.select('g.voronoi').selectAll('path').data(overlay); | ||
vmesh.exit().remove(); | ||
vmesh = vmesh.enter().append('path') | ||
.attr('fill', 'none') | ||
.attr('pointer-events', 'all') | ||
.merge(vmesh); | ||
.attr('fill', 'none') | ||
.attr('pointer-events', 'all') | ||
.merge(vmesh); | ||
vmesh.attr('d', d => d != null ? 'M' + d.join('L') + 'Z' : '') | ||
@@ -907,10 +930,10 @@ .attr('class', d => d != null ? 'series-' + d.data[2] : null); | ||
let fmtX = (v) => v; | ||
if (labelTime != null) { | ||
if (typeof labelTime === 'function') { | ||
fmtX = labelTime | ||
fmtX = labelTime | ||
} else if (labelTime === 'multi') { | ||
let tf = timeFormatLocale(localeTime).format; | ||
fmtX = timeMultiFormat({ localtime: false } , tf); | ||
fmtX = timeMultiFormat({ localtime: false } , tf); | ||
} else if (labelTime === 'multi-local') { | ||
@@ -920,7 +943,7 @@ let tf = timeFormatLocale(localeTime).format; | ||
// needs a refactor to properly support time zones | ||
fmtX = timeMultiFormat({ localtime: false } , tf); | ||
fmtX = timeMultiFormat({ localtime: false } , tf); | ||
} else { | ||
let tf = timeFormatLocale(localeTime); | ||
fmtX = tf.format(labelTime); | ||
fmtX = tf.format(labelTime); | ||
} | ||
@@ -931,6 +954,6 @@ } else if (typeof tickFormatIndex === 'function') { | ||
fmtX = formatLocale(localeFormat).format(tickFormatIndex); | ||
} | ||
} | ||
let fmtY = null; | ||
if (formatValue != null) { | ||
@@ -945,3 +968,3 @@ if (typeof formatValue === 'function') { | ||
_tipHtml = function (d,i,s) { | ||
@@ -961,3 +984,3 @@ let v = value(d); | ||
} | ||
if (fmtY != null && logValue === 0) { | ||
@@ -989,7 +1012,7 @@ y = fmtY(y); | ||
styleEl = styleEl.enter() | ||
.append('style') | ||
.attr('type', 'text/css') | ||
.attr('id', (id ? 'style-lines-' + id : null)) | ||
.attr('class', (id ? null : 'style-' + classed)) | ||
.merge(styleEl); | ||
.append('style') | ||
.attr('type', 'text/css') | ||
.attr('id', (id ? 'style-lines-' + id : null)) | ||
.attr('class', (id ? null : 'style-' + classed)) | ||
.merge(styleEl); | ||
styleEl.text(s => s); | ||
@@ -1000,5 +1023,5 @@ | ||
let i = d.data[3]; | ||
let item = data[s][i]; | ||
let item = _data[s][i]; | ||
if (stacked === true) { | ||
@@ -1009,13 +1032,11 @@ // Quick hack to ignore empty series by scanning downward | ||
if (s < 0) break; | ||
item = data[s][i]; | ||
item = _data[s][i]; | ||
} | ||
} | ||
let nested = item[1].data; | ||
if (nested !== undefined) { | ||
item = nested; | ||
} | ||
if (onClick) onClick(item); | ||
}); | ||
@@ -1026,5 +1047,5 @@ | ||
let i = d.data[3]; | ||
let item = data[s][i]; | ||
let item = _data[s][i]; | ||
let y = 0; | ||
@@ -1037,3 +1058,3 @@ | ||
if (s < 0) break; | ||
item = data[s][i]; | ||
item = _data[s][i]; | ||
} | ||
@@ -1045,8 +1066,8 @@ y = safeScaleV(item[1][1]); | ||
} | ||
let x = scaleI(item[0]); | ||
let nested = item[1].data; | ||
if (nested !== undefined) { | ||
@@ -1057,20 +1078,20 @@ item = nested; | ||
g.append('circle') | ||
.attr('r', DEFAULT_TIP_CIRCLE_SIZE) | ||
.attr('class', 'tip outline') | ||
.attr('cx', x) | ||
.attr('cy', y) | ||
.attr('pointer-events', 'none') | ||
.attr('fill', display[theme].axis); | ||
.attr('r', DEFAULT_TIP_CIRCLE_SIZE) | ||
.attr('class', 'tip outline') | ||
.attr('cx', x) | ||
.attr('cy', y) | ||
.attr('pointer-events', 'none') | ||
.attr('fill', display[theme].axis); | ||
let circle = g.append('circle') | ||
.attr('r', DEFAULT_TIP_CIRCLE_SIZE - widths.outline) | ||
.attr('class', 'tip fill') | ||
.attr('cx', x) | ||
.attr('cy', y) | ||
.attr('pointer-events', 'none') | ||
.attr('fill', colors(item, s)); | ||
.attr('r', DEFAULT_TIP_CIRCLE_SIZE - widths.outline) | ||
.attr('class', 'tip fill') | ||
.attr('cx', x) | ||
.attr('cy', y) | ||
.attr('pointer-events', 'none') | ||
.attr('fill', colors(item, s)); | ||
rtip.show.apply(circle.node(), [ item, i, s ]); | ||
}); | ||
elmS.on('mouseout', function () { | ||
@@ -1081,5 +1102,5 @@ g.selectAll('circle.tip').remove(); | ||
rtip.hide(); | ||
let labels = []; | ||
let labels = []; | ||
if (legendOrientation === 'voronoi') { | ||
@@ -1096,11 +1117,11 @@ const centerI = (scaleI.range()[1] - scaleI.range()[0]) / 2; | ||
} | ||
// will drag the text position towards the data point by a funciton of | ||
// will drag the text position towards the data point by a funciton of | ||
// voronoiAttraction | ||
let calculateTextPosition = function(centroid, point) { | ||
let angle = Math.atan2(centroid[1] - point[1], centroid[0] - point[0]); | ||
let x = centroid[0] - point[0]; | ||
let y = centroid[1] - point[1]; | ||
let l = Math.sqrt(x*x + y*y); | ||
@@ -1110,44 +1131,44 @@ | ||
} | ||
let polys = overlay.map(calculatePolygon); | ||
let candidates = nest() | ||
.key(d => d != null ? d.s : '') | ||
.sortValues((a,b) => descending(a.a, b.a)) | ||
.entries(polys) | ||
.filter(d => d.key !== '') | ||
.map(function (d) { | ||
for (let i=0; i < d.values.length; i++) { | ||
let e = d.values[i]; | ||
if (e != null) return e.i; | ||
} | ||
// nothing was an option | ||
return 0; | ||
}); | ||
.key(d => d != null ? d.s : '') | ||
.sortValues((a,b) => descending(a.a, b.a)) | ||
.entries(polys) | ||
.filter(d => d.key !== '') | ||
.map(function (d) { | ||
for (let i=0; i < d.values.length; i++) { | ||
let e = d.values[i]; | ||
if (e != null) return e.i; | ||
} | ||
// nothing was an option | ||
return 0; | ||
}); | ||
labels = candidates.map(i => calculateTextPosition(polys[i].c, [ scaleI(flat[i][0]), safeScaleV(flat[i][1]) ])); | ||
} | ||
let vlabels = g.select('g.voronoi').selectAll('text').data(labels); | ||
vlabels.exit().remove(); | ||
vlabels = vlabels.enter().append('text') | ||
.attr('text-anchor', 'middle') | ||
.attr('dominant-baseline', 'central') | ||
.merge(vlabels); | ||
vlabels = vlabels.enter().append('text') | ||
.attr('text-anchor', 'middle') | ||
.attr('dominant-baseline', 'central') | ||
.merge(vlabels); | ||
if (transition === true && animateLabels === true) { | ||
vlabels = vlabels.transition(context); | ||
} | ||
} | ||
vlabels.attr('x', d => d[0]) | ||
.attr('y', d => d[1]) | ||
.attr('fill', (d,i) => colors(d,i,'legend')) | ||
.attr('font-weight', fonts.variable.weightColor) | ||
.text((d, i) => i < legend.length ? legend[i] : ''); | ||
.attr('y', d => d[1]) | ||
.attr('fill', (d,i) => colors(d,i,'legend')) | ||
.attr('font-weight', fonts.variable.weightColor) | ||
.text((d, i) => i < legend.length ? legend[i] : ''); | ||
function _mapHighlights(e) { | ||
if (Array.isArray(e)) { | ||
return { l: e.map(fmtX).join(','), v: e }; | ||
return { l: e.map(fmtX).join(','), v: e }; | ||
} | ||
if (typeof e === 'object') { | ||
@@ -1160,22 +1181,22 @@ if (!Array.isArray(e.v)) { | ||
} | ||
return { l: fmtX(e), v: [ e ] } | ||
} | ||
let _highlightIndex = highlightIndex.map(_mapHighlights); | ||
let hIndex = g.select('g.highlight-v').selectAll('rect').data(_highlightIndex); | ||
hIndex.exit().remove(); | ||
hIndex = hIndex.enter().append('rect') | ||
.merge(hIndex); | ||
hIndex = hIndex.enter().append('rect') | ||
.merge(hIndex); | ||
let hLabel = g.select('g.highlight-v').selectAll('text').data(_highlightIndex); | ||
hLabel.exit().remove(); | ||
hLabel = hLabel.enter().append('text') | ||
.attr('dominant-baseline', 'text-after-edge') | ||
.merge(hLabel); | ||
hLabel = hLabel.enter().append('text') | ||
.attr('dominant-baseline', 'text-after-edge') | ||
.merge(hLabel); | ||
hLabel | ||
.attr('text-anchor', 'middle') | ||
.attr('class', d => d.c); | ||
.attr('text-anchor', 'middle') | ||
.attr('class', d => d.c); | ||
@@ -1186,19 +1207,19 @@ if (transition === true) { | ||
} | ||
hIndex.attr('y', _inset.top) | ||
.attr('height', h - _inset.bottom - _inset.top) | ||
.attr('x', d => Math.round(scaleI(d.v[0]) - (pattern.size() / 2))) | ||
.attr('width', function(d) { | ||
let sz = 1; | ||
if (d.v[1] != null) { | ||
sz = scaleI(d.v[1]) - scaleI(d.v[0]); | ||
} | ||
return pattern.align(sz); | ||
}) | ||
.attr('fill', pattern.url()); | ||
.attr('height', h - _inset.bottom - _inset.top) | ||
.attr('x', d => Math.round(scaleI(d.v[0]) - (pattern.size() / 2))) | ||
.attr('width', function(d) { | ||
let sz = 1; | ||
if (d.v[1] != null) { | ||
sz = scaleI(d.v[1]) - scaleI(d.v[0]); | ||
} | ||
return pattern.align(sz); | ||
}) | ||
.attr('fill', pattern.url()); | ||
hLabel.attr('x', d => d.v[1] == null ? scaleI(d.v[0]) + DEFAULT_HIGHLIGHT_PADDING : DEFAULT_HIGHLIGHT_PADDING + scaleI(d.v[0]) + (scaleI(d.v[1]) - scaleI(d.v[0]))/2 ) | ||
.attr('y', _inset.top) | ||
.text(d => d.l); | ||
.attr('y', _inset.top) | ||
.text(d => d.l); | ||
@@ -1374,3 +1395,7 @@ _ptrim = trim; | ||
_impl.legend = function(value) { | ||
return arguments.length ? (legend = _coerceArray(value), _impl) : legend; | ||
return arguments.length ? ( | ||
legend = _coerceArray(value), | ||
legendsEnabled = Object.keys(legend).map(i => parseInt(i)), | ||
_impl | ||
) : legend; | ||
}; | ||
@@ -1492,10 +1517,17 @@ | ||
return arguments.length ? (axisDisplayIndex = value, _impl) : axisDisplayIndex; | ||
}; | ||
_impl.onClick = function(value) { | ||
return arguments.length ? (onClick = value, _impl) : onClick; | ||
}; | ||
}; | ||
_impl.legendSize = function(value) { | ||
return arguments.length ? (legendSize = value, _impl) : legendSize; | ||
}; | ||
_impl.legendIsToggleable = function(value) { | ||
return arguments.length ? (legendIsToggleable = value, _impl) : legendIsToggleable; | ||
}; | ||
_impl.tintColor = function(value) { | ||
return arguments.length ? (tintColor = value, _impl) : tintColor; | ||
} | ||
return _impl; | ||
} |
@@ -23,3 +23,3 @@ var tape = require("@redsift/tape-reel")("<div id='test'></div>"), | ||
var el = d3.select('#test'); | ||
el.datum([ 1, 2 ]).call(host); | ||
el.datum([{l: 1, v:[1, 2]}]).call(host); | ||
@@ -31,4 +31,4 @@ t.equal(el.selectAll('svg').size(), 1); | ||
// In this chart, one path should be there | ||
t.equal(node.selectAll('path.stroke').size(), 1); | ||
t.equal(node.selectAll('path.area').size(), 1); | ||
t.equal(node.selectAll('path.stroke').size(), 2); | ||
t.equal(node.selectAll('path.area').size(), 2); | ||
@@ -42,3 +42,3 @@ t.end(); | ||
var el = d3.select('#test'); | ||
el.datum([ [ 0, 1 ], [ 1, 2 ] ]).call(host); | ||
el.datum([ {l: 1, v:[ 0, 1 ]}, {l: 2, v:[ 1, 2 ]} ]).call(host); | ||
@@ -53,3 +53,3 @@ t.equal(el.selectAll('svg').size(), 1); | ||
t.equal(node.selectAll('.voronoi path.series-0').size(), 2); | ||
t.equal(node.selectAll('.voronoi path.series-0').size(), 0); | ||
t.equal(node.selectAll('.voronoi path.series-1').size(), 2); | ||
@@ -63,3 +63,3 @@ | ||
tape("html() data reentrant", function(t) { | ||
var data = [ [ 0, 1 ], [ 1, 2 ] ]; | ||
var data = [ {v:[ 0, 1 ]}, {v:[ 1, 2 ]} ]; | ||
@@ -91,3 +91,3 @@ var host = lines.html(); | ||
var el = d3.select('#test'); | ||
el.datum([ [ 0, 1 ], [ 1, 2 ] ]).call(host); | ||
el.datum([ {v:[ 0, 1 ]}, {v:[ 1, 2 ]} ]).call(host); | ||
@@ -97,5 +97,5 @@ t.equal(el.selectAll('svg').size(), 1); | ||
t.equal(el.selectAll('.voronoi path').size(), 4, '4 voronoi polygons'); | ||
t.equal(el.selectAll('.voronoi text').size(), 2, '2 text labels'); | ||
t.equal(el.selectAll('.voronoi text').size(), 1, '1 text labels'); | ||
el.datum([ [ 0, 1 ] ]).call(host); | ||
el.datum([ {v: [ 0, 1 ]} ]).call(host); | ||
@@ -102,0 +102,0 @@ t.equal(el.selectAll('.voronoi path').size(), 2, '2 voronoi polygons'); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
12
1
109
0
84670
10
1409
2
+ Added@redsift/d3-rs-intl@0.3.0(transitive)
+ Added@redsift/d3-rs-legends@0.4.0(transitive)
+ Added@redsift/d3-rs-svg@0.7.0(transitive)
+ Added@redsift/d3-rs-theme@0.6.0(transitive)
+ Added@redsift/d3-rs-tip@0.10.0(transitive)
+ Addedd3-transition@1.3.2(transitive)
- Removed@redsift/d3-rs-intl@0.1.0(transitive)
- Removed@redsift/d3-rs-legends@0.2.5(transitive)
- Removed@redsift/d3-rs-svg@0.4.00.5.2(transitive)
- Removed@redsift/d3-rs-theme@0.4.2(transitive)
- Removed@redsift/d3-rs-tip@0.6.0(transitive)
- Removedd3-selection@1.2.0(transitive)
- Removedd3-transition@1.1.3(transitive)
Updated@redsift/d3-rs-intl@0.3.0
Updated@redsift/d3-rs-legends@0.4.0
Updated@redsift/d3-rs-svg@0.7.0
Updated@redsift/d3-rs-theme@0.6.0
Updated@redsift/d3-rs-tip@0.10.0