New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

d3-timeline-chart

Package Overview
Dependencies
Maintainers
2
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-timeline-chart - npm Package Compare versions

Comparing version 1.0.3 to 1.2.0

393

dist/timeline-chart.js

@@ -1,221 +0,264 @@

'use strict';
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(['module'], factory);
} else if (typeof exports !== "undefined") {
factory(module);
} else {
var mod = {
exports: {}
};
factory(mod);
global.TimelineChart = mod.exports;
}
})(this, function (module) {
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
var TimelineChart = function () {
function TimelineChart(element, data, opts) {
_classCallCheck(this, TimelineChart);
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var self = this;
var TimelineChart = function () {
function TimelineChart(element, data, opts) {
_classCallCheck(this, TimelineChart);
element.classList.add('timeline-chart');
var self = this;
var options = this.extendOptions(opts);
element.classList.add('timeline-chart');
var allElements = data.reduce(function (agg, e) {
return agg.concat(e.data);
}, []);
var options = this.extendOptions(opts);
var minDt = d3.min(allElements, this.getPointMinDt);
var maxDt = d3.max(allElements, this.getPointMaxDt);
var allElements = data.reduce(function (agg, e) {
return agg.concat(e.data);
}, []);
var elementWidth = options.width || element.clientWidth;
var elementHeight = options.height || element.clientHeight;
var minDt = d3.min(allElements, this.getPointMinDt);
var maxDt = d3.max(allElements, this.getPointMaxDt);
var margin = {
top: 0,
right: 0,
bottom: 20,
left: 0
};
var elementWidth = options.width || element.clientWidth;
var elementHeight = options.height || element.clientHeight;
var width = elementWidth - margin.left - margin.right;
var height = elementHeight - margin.top - margin.bottom;
var margin = {
top: 0,
right: 0,
bottom: 20,
left: 0
};
var groupWidth = 200;
var width = elementWidth - margin.left - margin.right;
var height = elementHeight - margin.top - margin.bottom;
var x = d3.time.scale().domain([minDt, maxDt]).range([groupWidth, width]);
var groupWidth = 200;
var xAxis = d3.svg.axis().scale(x).orient('bottom').tickSize(-height);
var x = d3.time.scale().domain([minDt, maxDt]).range([groupWidth, width]);
var zoom = d3.behavior.zoom().x(x).on('zoom', zoomed);
var xAxis = d3.svg.axis().scale(x).orient('bottom').tickSize(-height);
var svg = d3.select(element).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')').call(zoom);
var zoom = d3.behavior.zoom().x(x).on('zoom', zoomed);
svg.append('defs').append('clipPath').attr('id', 'chart-content').append('rect').attr('x', groupWidth).attr('y', 0).attr('height', height).attr('width', width - groupWidth);
var svg = d3.select(element).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')').call(zoom);
svg.append('rect').attr('class', 'chart-bounds').attr('x', groupWidth).attr('y', 0).attr('height', height).attr('width', width - groupWidth);
svg.append('defs').append('clipPath').attr('id', 'chart-content').append('rect').attr('x', groupWidth).attr('y', 0).attr('height', height).attr('width', width - groupWidth);
svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,' + height + ')').call(xAxis);
svg.append('rect').attr('class', 'chart-bounds').attr('x', groupWidth).attr('y', 0).attr('height', height).attr('width', width - groupWidth);
var groupHeight = height / data.length;
var groupSection = svg.selectAll('.group-section').data(data).enter().append('line').attr('class', 'group-section').attr('x1', 0).attr('x2', width).attr('y1', function (d, i) {
return groupHeight * (i + 1);
}).attr('y2', function (d, i) {
return groupHeight * (i + 1);
});
svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,' + height + ')').call(xAxis);
var groupLabels = svg.selectAll('.group-label').data(data).enter().append('text').attr('class', 'group-label').attr('x', 0).attr('y', function (d, i) {
return groupHeight * i + groupHeight / 2 + 5.5;
}).attr('dx', '0.5em').text(function (d) {
return d.label;
});
var groupHeight = height / data.length;
var groupSection = svg.selectAll('.group-section').data(data).enter().append('line').attr('class', 'group-section').attr('x1', 0).attr('x2', width).attr('y1', function (d, i) {
return groupHeight * (i + 1);
}).attr('y2', function (d, i) {
return groupHeight * (i + 1);
});
var lineSection = svg.append('line').attr('x1', groupWidth).attr('x2', groupWidth).attr('y1', 0).attr('y2', height).attr('stroke', 'black');
var groupIntervalItems = svg.selectAll('.group-interval-item').data(data).enter().append('g').attr('clip-path', 'url(#chart-content)').attr('class', 'item').attr('transform', function (d, i) {
return 'translate(0, ' + groupHeight * i + ')';
}).selectAll('.dot').data(function (d) {
return d.data.filter(function (_) {
return _.type === TimelineChart.TYPE.INTERVAL;
var groupLabels = svg.selectAll('.group-label').data(data).enter().append('text').attr('class', 'group-label').attr('x', 0).attr('y', function (d, i) {
return groupHeight * i + groupHeight / 2 + 5.5;
}).attr('dx', '0.5em').text(function (d) {
return d.label;
});
}).enter();
var intervalBarHeight = 0.8 * groupHeight;
var intervalBarMargin = (groupHeight - intervalBarHeight) / 2;
var intervals = groupIntervalItems.append('rect').attr('class', 'interval').attr('width', function (d) {
return x(d.to) - x(d.from);
}).attr('height', intervalBarHeight).attr('y', intervalBarMargin).attr('x', function (d) {
return x(d.from);
});
var lineSection = svg.append('line').attr('x1', groupWidth).attr('x2', groupWidth).attr('y1', 0).attr('y2', height).attr('stroke', 'black');
var intervalTexts = groupIntervalItems.append('text').text(function (d) {
return d.label;
}).attr('fill', 'white').attr('class', 'interval-text').attr('y', groupHeight / 2 + 5).attr('x', function (d) {
return x(d.from);
});
var groupIntervalItems = svg.selectAll('.group-interval-item').data(data).enter().append('g').attr('clip-path', 'url(#chart-content)').attr('class', 'item').attr('transform', function (d, i) {
return 'translate(0, ' + groupHeight * i + ')';
}).selectAll('.dot').data(function (d) {
return d.data.filter(function (_) {
return _.type === TimelineChart.TYPE.INTERVAL;
});
}).enter();
var groupDotItems = svg.selectAll('.group-dot-item').data(data).enter().append('g').attr('clip-path', 'url(#chart-content)').attr('class', 'item').attr('transform', function (d, i) {
return 'translate(0, ' + groupHeight * i + ')';
}).selectAll('.dot').data(function (d) {
return d.data.filter(function (_) {
return _.type === TimelineChart.TYPE.POINT;
var intervalBarHeight = 0.8 * groupHeight;
var intervalBarMargin = (groupHeight - intervalBarHeight) / 2;
var intervals = groupIntervalItems.append('rect').attr('class', withCustom('interval')).attr('width', function (d) {
return Math.max(options.intervalMinWidth, x(d.to) - x(d.from));
}).attr('height', intervalBarHeight).attr('y', intervalBarMargin).attr('x', function (d) {
return x(d.from);
});
}).enter();
var dots = groupDotItems.append('circle').attr('class', 'dot').attr('cx', function (d) {
return x(d.at);
}).attr('cy', groupHeight / 2).attr('r', 5);
var intervalTexts = groupIntervalItems.append('text').text(function (d) {
return d.label;
}).attr('fill', 'white').attr('class', withCustom('interval-text')).attr('y', groupHeight / 2 + 5).attr('x', function (d) {
return x(d.from);
});
if (options.tip) {
if (d3.tip) {
var tip = d3.tip().attr('class', 'd3-tip').html(options.tip);
svg.call(tip);
dots.on('mouseover', tip.show).on('mouseout', tip.hide);
} else {
console.error('Please make sure you have d3.tip included as dependency (https://github.com/Caged/d3-tip)');
var groupDotItems = svg.selectAll('.group-dot-item').data(data).enter().append('g').attr('clip-path', 'url(#chart-content)').attr('class', 'item').attr('transform', function (d, i) {
return 'translate(0, ' + groupHeight * i + ')';
}).selectAll('.dot').data(function (d) {
return d.data.filter(function (_) {
return _.type === TimelineChart.TYPE.POINT;
});
}).enter();
var dots = groupDotItems.append('circle').attr('class', withCustom('dot')).attr('cx', function (d) {
return x(d.at);
}).attr('cy', groupHeight / 2).attr('r', 5);
if (options.tip) {
if (d3.tip) {
var tip = d3.tip().attr('class', 'd3-tip').html(options.tip);
svg.call(tip);
dots.on('mouseover', tip.show).on('mouseout', tip.hide);
} else {
console.error('Please make sure you have d3.tip included as dependency (https://github.com/Caged/d3-tip)');
}
}
}
zoomed();
zoomed();
function zoomed() {
if (self.onVizChangeFn && d3.event) {
self.onVizChangeFn.call(self, {
scale: d3.event.scale,
translate: d3.event.translate,
domain: x.domain()
});
function withCustom(defaultClass) {
return function (d) {
return d.customClass ? [d.customClass, defaultClass].join(' ') : defaultClass;
};
}
svg.select('.x.axis').call(xAxis);
function zoomed() {
if (self.onVizChangeFn && d3.event) {
self.onVizChangeFn.call(self, {
scale: d3.event.scale,
translate: d3.event.translate,
domain: x.domain()
});
}
svg.selectAll('circle.dot').attr('cx', function (d) {
return x(d.at);
});
svg.selectAll('rect.interval').attr('x', function (d) {
return x(d.from);
}).attr('width', function (d) {
return x(d.to) - x(d.from);
});
svg.select('.x.axis').call(xAxis);
svg.selectAll('.interval-text').attr('x', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return positionData.upToPosition;
} else if (positionData.xPosition < groupWidth && positionData.upToPosition > groupWidth) {
return groupWidth;
}
return positionData.xPosition;
}).attr('text-anchor', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return 'end';
}
return 'start';
}).attr('dx', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return '-0.5em';
}
return '0.5em';
}).text(function (d) {
var positionData = getTextPositionData.call(this, d);
var percent = (positionData.width - options.textTruncateThreshold) / positionData.textWidth;
if (percent < 1) {
if (positionData.width > options.textTruncateThreshold) {
return d.label.substr(0, Math.floor(d.label.length * percent)) + '...';
} else {
return '';
svg.selectAll('circle.dot').attr('cx', function (d) {
return x(d.at);
});
svg.selectAll('rect.interval').attr('x', function (d) {
return x(d.from);
}).attr('width', function (d) {
return Math.max(options.intervalMinWidth, x(d.to) - x(d.from));
});
svg.selectAll('.interval-text').attr('x', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return positionData.upToPosition;
} else if (positionData.xPosition < groupWidth && positionData.upToPosition > groupWidth) {
return groupWidth;
}
return positionData.xPosition;
}).attr('text-anchor', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return 'end';
}
return 'start';
}).attr('dx', function (d) {
var positionData = getTextPositionData.call(this, d);
if (positionData.upToPosition - groupWidth - 10 < positionData.textWidth) {
return '-0.5em';
}
return '0.5em';
}).text(function (d) {
var positionData = getTextPositionData.call(this, d);
var percent = (positionData.width - options.textTruncateThreshold) / positionData.textWidth;
if (percent < 1) {
if (positionData.width > options.textTruncateThreshold) {
return d.label.substr(0, Math.floor(d.label.length * percent)) + '...';
} else {
return '';
}
}
return d.label;
});
function getTextPositionData(d) {
this.textSizeInPx = this.textSizeInPx || this.getComputedTextLength();
var from = x(d.from);
var to = x(d.to);
return {
xPosition: from,
upToPosition: to,
width: to - from,
textWidth: this.textSizeInPx
};
}
}
}
return d.label;
});
_createClass(TimelineChart, [{
key: 'extendOptions',
value: function extendOptions() {
var ext = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
function getTextPositionData(d) {
this.textSizeInPx = this.textSizeInPx || this.getComputedTextLength();
var from = x(d.from);
var to = x(d.to);
return {
xPosition: from,
upToPosition: to,
width: to - from,
textWidth: this.textSizeInPx
var defaultOptions = {
intervalMinWidth: 8, // px
tip: undefined,
textTruncateThreshold: 30
};
Object.keys(ext).map(function (k) {
return defaultOptions[k] = ext[k];
});
return defaultOptions;
}
}
}
}, {
key: 'getPointMinDt',
value: function getPointMinDt(p) {
return p.type === TimelineChart.TYPE.POINT ? p.at : p.from;
}
}, {
key: 'getPointMaxDt',
value: function getPointMaxDt(p) {
return p.type === TimelineChart.TYPE.POINT ? p.at : p.to;
}
}, {
key: 'onVizChange',
value: function onVizChange(fn) {
this.onVizChangeFn = fn;
return this;
}
}]);
_createClass(TimelineChart, [{
key: 'extendOptions',
value: function extendOptions() {
var ext = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
return TimelineChart;
}();
var defaultOptions = {
tip: undefined,
textTruncateThreshold: 30
};
Object.keys(ext).map(function (k) {
return defaultOptions[k] = ext[k];
});
return defaultOptions;
}
}, {
key: 'getPointMinDt',
value: function getPointMinDt(p) {
return p.type === TimelineChart.TYPE.POINT ? p.at : p.from;
}
}, {
key: 'getPointMaxDt',
value: function getPointMaxDt(p) {
return p.type === TimelineChart.TYPE.POINT ? p.at : p.to;
}
}, {
key: 'onVizChange',
value: function onVizChange(fn) {
this.onVizChangeFn = fn;
return this;
}
}]);
TimelineChart.TYPE = {
POINT: Symbol(),
INTERVAL: Symbol()
};
return TimelineChart;
}();
TimelineChart.TYPE = {
POINT: Symbol(),
INTERVAL: Symbol()
};
module.exports = TimelineChart;
});
//# sourceMappingURL=timeline-chart.js.map

@@ -9,2 +9,3 @@ (() => {

const sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');

@@ -26,2 +27,3 @@ gulp.task('js:build', () => {

.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(gulp.dest('./dist'));

@@ -28,0 +30,0 @@ });

@@ -110,3 +110,2 @@ class TimelineChart {

let intervalBarHeight = 0.8 * groupHeight;

@@ -116,4 +115,4 @@ let intervalBarMargin = (groupHeight - intervalBarHeight) / 2;

.append('rect')
.attr('class', 'interval')
.attr('width', (d) => x(d.to) - x(d.from))
.attr('class', withCustom('interval'))
.attr('width', (d) => Math.max(options.intervalMinWidth, x(d.to) - x(d.from)))
.attr('height', intervalBarHeight)

@@ -127,3 +126,3 @@ .attr('y', intervalBarMargin)

.attr('fill', 'white')
.attr('class', 'interval-text')
.attr('class', withCustom('interval-text'))
.attr('y', (groupHeight / 2) + 5)

@@ -147,3 +146,3 @@ .attr('x', (d) => x(d.from));

.append('circle')
.attr('class', 'dot')
.attr('class', withCustom('dot'))
.attr('cx', d => x(d.at))

@@ -165,2 +164,6 @@ .attr('cy', groupHeight / 2)

function withCustom(defaultClass) {
return d => d.customClass ? [d.customClass, defaultClass].join(' ') : defaultClass
}
function zoomed() {

@@ -178,3 +181,3 @@ if (self.onVizChangeFn && d3.event) {

svg.selectAll('circle.dot').attr('cx', d => x(d.at));
svg.selectAll('rect.interval').attr('x', d => x(d.from)).attr('width', d => x(d.to) - x(d.from));
svg.selectAll('rect.interval').attr('x', d => x(d.from)).attr('width', d => Math.max(options.intervalMinWidth, x(d.to) - x(d.from)));

@@ -231,2 +234,3 @@ svg.selectAll('.interval-text').attr('x', function(d) {

let defaultOptions = {
intervalMinWidth: 8, // px
tip: undefined,

@@ -254,1 +258,3 @@ textTruncateThreshold: 30

};
module.exports = TimelineChart;
{
"name": "d3-timeline-chart",
"version": "1.0.3",
"version": "1.2.0",
"description": "",

@@ -16,2 +16,4 @@ "main": "dist/timeline-chart.js",

"devDependencies": {
"babel-plugin-rename-umd-globals": "0.0.2",
"babel-plugin-transform-es2015-modules-umd": "^6.8.0",
"babel-preset-es2015": "^6.5.0",

@@ -21,2 +23,3 @@ "d3": "^3.5.16",

"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.0",
"gulp-babel": "^6.1.2",

@@ -23,0 +26,0 @@ "gulp-sass": "^2.2.0",

describe('TimelineChart', () => {
'use strict';
const WRAPPER_CLASS = 'chart-wrapper';
it('should append a SVG element to given selection', () => {
const div = document.createElement('div');
const div = getDefaultSizeContainer();
const data = [{

@@ -14,2 +16,75 @@ label: 'foo',

});
describe('custom class', () => {
describe('point element', () => {
it('should add to the circle element', () => {
const div = getDefaultSizeContainer();
const data = [{
label: 'Group 1',
data: [{
at: new Date([2015, 1, 1]),
type: TimelineChart.TYPE.POINT,
customClass: 'custom-class'
}]
}];
const chart = new TimelineChart(div, data);
expect(div.querySelectorAll('circle.custom-class').length).toBe(1);
});
});
describe('interval element', () => {
it('should add class to rect and to text', () => {
const div = getDefaultSizeContainer();
const data = [{
label: 'Group 1',
data: [{
from: new Date([2015, 1, 1]),
to: new Date([2015, 1, 2]),
type: TimelineChart.TYPE.INTERVAL,
customClass: 'custom-class-interval',
label: 'Test'
}]
}];
const chart = new TimelineChart(div, data);
expect(div.querySelectorAll('rect.custom-class-interval').length).toBe(1);
expect(div.querySelectorAll('text.custom-class-interval').length).toBe(1);
})
});
});
describe('min interval width', () => {
function matchWidth(w, cfg) {
return function() {
const div = getDefaultSizeContainer();
const data = [{
label: 'Group 1',
data: [{
from: new Date([2015, 1, 1]),
to: new Date([2015, 1, 1]),
type: TimelineChart.TYPE.INTERVAL,
customClass: 'custom-class-interval',
label: 'Test'
}]
}];
const chart = new TimelineChart(div, data, cfg);
const currentWidth = div.querySelector('rect.custom-class-interval').getAttribute('width');
expect(currentWidth == w).toBeTruthy();
}
}
it('should default equals to 8', matchWidth(8, {}));
it('should be able to change default min width', matchWidth(5, {intervalMinWidth: 5}));
});
function getDefaultSizeContainer() {
const div = document.createElement('div');
div.setAttribute('class', WRAPPER_CLASS);
div.setAttribute('style','width:800px; height: 200px;');
return div;
}
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc