describe('c3 chart tooltip', function () { 'use strict'; var chart; var tooltipConfiguration = {}; var dataOrder = 'desc'; var dataGroups; var args = function () { return { data: { columns: [ ['data1', 30, 200, 100, 400, 150, 250], // 1130 ['data2', 50, 20, 10, 40, 15, 25], // 160 ['data3', 150, 120, 110, 140, 115, 125] // 760 ], order: dataOrder, groups: dataGroups, }, tooltip: tooltipConfiguration }; }; beforeEach(function (done) { chart = window.initChart(chart, args(), done); dataOrder = 'desc'; dataGroups = undefined; }); describe('tooltip position', function () { beforeAll(function () { tooltipConfiguration = {}; }); describe('without left margin', function () { it('should show tooltip on proper position', function () { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(1), y = chart.internal.y(200); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var tooltipContainer = d3.select('.c3-tooltip-container'), top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')), left = Math.floor(+tooltipContainer.style('left').replace(/px/, '')); expect(top).toBeGreaterThan(0); expect(left).toBeGreaterThan(0); }); }); describe('with left margin', function () { beforeAll(function () { d3.select('#chart').style('margin-left', '300px'); }); it('should show tooltip on proper position', function () { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(1) + 300, // add margin-left y = chart.internal.y(200); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var tooltipContainer = d3.select('.c3-tooltip-container'), top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')), left = Math.floor(+tooltipContainer.style('left').replace(/px/, '')); expect(top).toBeGreaterThan(0); expect(left).toBeGreaterThan(0); }); afterAll(function () { d3.select('#chart').style('margin-left', null); }); }); }); describe('tooltip positionFunction', function () { var topExpected = 37, leftExpected = 79; beforeAll(function () { tooltipConfiguration = { position: function (data, width, height, element) { expect(data.length).toBe(args().data.columns.length); expect(data[0]).toEqual(jasmine.objectContaining({ index: 2, value: 100, id: 'data1' })); expect(width).toBeGreaterThan(0); expect(height).toBeGreaterThan(0); expect(element).toBe(d3.select('.c3-event-rect').node()); return {top: topExpected, left: leftExpected}; } }; }); it('should be set to the coordinate where the function returned', function () { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var tooltipContainer = d3.select('.c3-tooltip-container'), top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')), left = Math.floor(+tooltipContainer.style('left').replace(/px/, '')); expect(top).toBeGreaterThan(0); expect(left).toBeGreaterThan(0); }); }); describe('tooltip getTooltipContent', function () { beforeAll(function () { tooltipConfiguration = { data_order: 'desc' }; }); it('should sort values desc', function () { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data3'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data2'); }); }); describe('tooltip with data_order as desc with grouped data', function() { beforeAll(function() { dataOrder = 'desc'; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each data in descending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data1'); // 1130 expect(classes[2]).toBe('c3-tooltip-name--data3'); // 760 expect(classes[3]).toBe('c3-tooltip-name--data2'); // 160 }); }); describe('tooltip with data_order as asc with grouped data', function() { beforeAll(function() { dataOrder = 'asc'; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each data in ascending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); // 160 expect(classes[2]).toBe('c3-tooltip-name--data3'); // 760 expect(classes[3]).toBe('c3-tooltip-name--data1'); // 1130 }); }); describe('tooltip with data_order as NULL with grouped data', function() { beforeAll(function() { dataOrder = null; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each data in given order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data1'); expect(classes[2]).toBe('c3-tooltip-name--data2'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with data_order as Function with grouped data', function() { beforeAll(function() { var order = [ 'data2', 'data1', 'data3' ]; dataOrder = function(data1, data2) { return order.indexOf(data1.id) - order.indexOf(data2.id); }; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each data in order given by function', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with data_order as Array with grouped data', function() { beforeAll(function() { dataOrder = [ 'data2', 'data1', 'data3' ]; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each data in order given by array', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with data_order as desc with un-grouped data', function() { beforeAll(function() { dataOrder = 'desc'; }); it('should display each tooltip value descending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data3'); // 110 expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100 expect(classes[3]).toBe('c3-tooltip-name--data2'); // 10 }); }); describe('tooltip with data_order as asc with un-grouped data', function() { beforeAll(function() { dataOrder = 'asc'; }); it('should display each tooltip value in ascending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); // 10 expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100 expect(classes[3]).toBe('c3-tooltip-name--data3'); // 110 }); }); describe('tooltip with data_order as NULL with un-grouped data', function() { beforeAll(function() { dataOrder = null; }); it('should display each tooltip value in given data order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data1'); expect(classes[2]).toBe('c3-tooltip-name--data2'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with data_order as Function with un-grouped data', function() { beforeAll(function() { var order = [ 'data2', 'data1', 'data3' ]; dataOrder = function(data1, data2) { return order.indexOf(data1.id) - order.indexOf(data2.id); }; }); it('should display each tooltip value in data order given by function', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with data_order as Array with un-grouped data', function() { beforeAll(function() { dataOrder = [ 'data2', 'data1', 'data3' ]; }); it('should display each tooltip value in data order given by array', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with tooltip_order as desc', function() { beforeAll(function() { tooltipConfiguration = { order: 'desc' }; // this should be ignored dataOrder = 'asc'; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each tooltip value descending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data3'); // 110 expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100 expect(classes[3]).toBe('c3-tooltip-name--data2'); // 10 }); }); describe('tooltip with tooltip_order as asc', function() { beforeAll(function() { tooltipConfiguration = { order: 'asc' }; // this should be ignored dataOrder = 'desc'; dataGroups = [ [ 'data1', 'data2', 'data3' ]]; }); it('should display each tooltip value in ascending order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(220); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); // 10 expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100 expect(classes[3]).toBe('c3-tooltip-name--data3'); // 110 }); }); describe('tooltip with tooltip_order as NULL', function() { beforeAll(function() { tooltipConfiguration = { order: null }; }); it('should display each tooltip value in given order', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data1'); expect(classes[2]).toBe('c3-tooltip-name--data2'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with tooltip_order as Function', function() { beforeAll(function() { var order = [ 'data2', 'data1', 'data3' ]; tooltipConfiguration = { order: function(data1, data2) { return order.indexOf(data1.id) - order.indexOf(data2.id); } }; }); it('should display each tooltip value in data order given by function', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); describe('tooltip with tooltip_order as Array', function() { beforeAll(function() { tooltipConfiguration = { order: [ 'data2', 'data1', 'data3' ] }; }); it('should display each tooltip value in data order given by array', function() { var eventRect = d3.select('.c3-event-rect').node(), x = chart.internal.x(2), y = chart.internal.y(100); window.setMouseEvent(chart, 'mousemove', x, y, eventRect); var classes = d3.selectAll('.c3-tooltip tr').nodes().map(function(node) { return node.className; }); expect(classes[0]).toBe(''); // header expect(classes[1]).toBe('c3-tooltip-name--data2'); expect(classes[2]).toBe('c3-tooltip-name--data1'); expect(classes[3]).toBe('c3-tooltip-name--data3'); }); }); });