From 8b843e028a41068200245ef7c8d859c3159223f1 Mon Sep 17 00:00:00 2001 From: Kristoffer Lind Date: Thu, 14 Feb 2019 11:08:34 +0100 Subject: [PATCH 01/24] fix excel export --- src/excel-export.js | 144 +++++++++++---------- src/export-button.jsx | 19 ++- src/headers-table/export-column-header.jsx | 8 +- src/headers-table/index.jsx | 1 + src/initialize-transformed.js | 5 +- src/paint.jsx | 3 - 6 files changed, 101 insertions(+), 79 deletions(-) diff --git a/src/excel-export.js b/src/excel-export.js index 9734e8c..ff67e12 100644 --- a/src/excel-export.js +++ b/src/excel-export.js @@ -1,73 +1,75 @@ -import $ from 'jquery'; +function buildTableHTML (title, subtitle, footnote) { + const titleHTML = `

${title}

`; + const subtitleHTML = `

${subtitle}

`; + const footnoteHTML = `

Note:${footnote}

`; + const dataTableClone = document.querySelector('.data-table').cloneNode(true); + const tableHTML = ` + + + + + + + ${titleHTML.length > 0 ? titleHTML : ''} + ${subtitleHTML.length > 0 ? subtitleHTML : ''} + ${footnoteHTML.length > 0 ? footnoteHTML : ''} + ${dataTableClone.outerHTML} + + + `.split('>.<') + .join('><') + .split('>*<') + .join('><'); -const isIE = /* @cc_on!@*/false || Boolean(document.documentMode); -const isChrome = Boolean(window.chrome) && Boolean(window.chrome.webstore); -const isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; -const isFirefox = typeof InstallTrigger !== 'undefined'; - -export function enableExcelExport (layout, f) { - let myTitle = ''; - let mySubTitle = ''; - let myFootNote = ''; - if (layout.title.length > 0) { - myTitle += '

'; - myTitle += layout.title; - myTitle += '

'; - } - if (layout.subtitle.length > 0) { - mySubTitle += '

'; - mySubTitle += layout.subtitle; - mySubTitle += '

'; - } - if (layout.footnote.length > 0) { - myFootNote += '

Note:'; - myFootNote += layout.footnote; - myFootNote += '

'; - } - - $('.icon-xls').on('click', () => { - $('.header-wrapper th').children('.tooltip') - .remove(); // remove some popup effects when exporting - $('.header-wrapper th').children('.icon-xls') - .remove(); // remove the xls icon when exporting - if (isChrome || isSafari) { - const $clonedDiv = $('.data-table').clone(true); // .kpi-table a secas exporta la 1ÂȘcol - let vEncodeHead = ''; - vEncodeHead += myTitle + mySubTitle + myFootNote; - const vEncode = encodeURIComponent($clonedDiv.html()); - let vDecode = `${vEncodeHead + vEncode}`; - - $clonedDiv.find('tr.header'); - vDecode = vDecode.split('%3E.%3C').join('%3E%3C'); - window.open(`data:application/vnd.ms-excel,${vDecode}`); - $.preventDefault(); - } - if (isIE) { - let a = ''; - a += myTitle + mySubTitle + myFootNote; - a += f; - a = a.split('>.<').join('><'); - a += ''; - - const w = window.open(); - w.document.open(); - w.document.write(a); - w.document.close(); - w.document.execCommand('SaveAs', true, 'Analysis.xls' || 'c:\TMP'); - w.close(); - } - - if (isFirefox) { - const $clonedDiv = $('.data-table').clone(true);// .kpi-table a secas exporta la 1ÂȘcol - let vEncodeHead = ''; - vEncodeHead += myTitle + mySubTitle + myFootNote; - const vEncode = encodeURIComponent($clonedDiv.html()); - let vDecode = `${vEncodeHead + vEncode}`; - - $clonedDiv.find('tr.header'); - vDecode = vDecode.split('>.<').join('><'); - window.open(`data:application/vnd.ms-excel,${vDecode}`); - $.preventDefault(); - } - }); + return tableHTML; +} + +function downloadXLS (html) { + const filename = 'analysis.xls'; + // IE/Edge + if (window.navigator.msSaveOrOpenBlob) { + const blobObject = new Blob([html]); + return window.navigator.msSaveOrOpenBlob(blobObject, filename); + } + + const dataURI = generateDataURI(html); + const link = window.document.createElement('a'); + link.href = dataURI; + link.download = filename; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + return true; +} + +function generateDataURI (html) { + const dataType = 'data:application/vnd.ms-excel;base64,'; + const data = window.btoa(unescape(encodeURIComponent(html))); + + return `${dataType}${data}`; +} + +export function exportXLS (title, subtitle, footnote) { + // close all tooltips (awaiting tooltips rewrite, should add a close all action for it) + // original was removing icon when starting export, disable and some spinner instead, shouldn't take enough time to warrant either..? + const table = buildTableHTML(title, subtitle, footnote); + downloadXLS(table); } diff --git a/src/export-button.jsx b/src/export-button.jsx index 60ea0d2..76436ed 100644 --- a/src/export-button.jsx +++ b/src/export-button.jsx @@ -1,13 +1,27 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { exportXLS } from './excel-export'; -// TODO: move interaction logic in here from excel-export.js class ExportButton extends React.PureComponent { + constructor (props) { + super(props); + this.handleExport = this.handleExport.bind(this); + } + + handleExport () { + const { excelExport, general } = this.props; + const { title, subtitle, footnote } = general; + if (excelExport) { + exportXLS(title, subtitle, footnote); + } + } + render () { const { excelExport } = this.props; return excelExport === true && ( @@ -20,7 +34,8 @@ ExportButton.defaultProps = { }; ExportButton.propTypes = { - excelExport: PropTypes.bool + excelExport: PropTypes.bool, + general: PropTypes.shape({}).isRequired }; export default ExportButton; diff --git a/src/headers-table/export-column-header.jsx b/src/headers-table/export-column-header.jsx index 640e89e..96fe045 100644 --- a/src/headers-table/export-column-header.jsx +++ b/src/headers-table/export-column-header.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ExportButton from '../export-button.jsx'; -const ExportColumnHeader = ({ baseCSS, title, allowExcelExport, hasSecondDimension, styling }) => { +const ExportColumnHeader = ({ baseCSS, general, title, allowExcelExport, hasSecondDimension, styling }) => { const rowSpan = hasSecondDimension ? 2 : 1; const style = { ...baseCSS, @@ -19,7 +19,10 @@ const ExportColumnHeader = ({ baseCSS, title, allowExcelExport, hasSecondDimensi rowSpan={rowSpan} style={style} > - + {title} ); @@ -28,6 +31,7 @@ const ExportColumnHeader = ({ baseCSS, title, allowExcelExport, hasSecondDimensi ExportColumnHeader.propTypes = { allowExcelExport: PropTypes.bool.isRequired, baseCSS: PropTypes.shape({}).isRequired, + general: PropTypes.shape({}).isRequired, hasSecondDimension: PropTypes.bool.isRequired, styling: PropTypes.shape({ headerOptions: PropTypes.shape({ diff --git a/src/headers-table/index.jsx b/src/headers-table/index.jsx index c45fa48..06db659 100644 --- a/src/headers-table/index.jsx +++ b/src/headers-table/index.jsx @@ -29,6 +29,7 @@ const HeadersTable = ({ data, general, styling }) => { dimensionInfo.qStateCounts.qSelected) diff --git a/src/paint.jsx b/src/paint.jsx index 2ed949d..9b5b691 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -1,5 +1,4 @@ import $ from 'jquery'; -import { enableExcelExport } from './excel-export'; import initializeStore from './store'; import React from 'react'; // import ReactDOM from 'react-dom'; @@ -182,8 +181,6 @@ export default async function paint ($element, layout, component) { $(this).toggleClass('selected'); }); - enableExcelExport(layout, html); - // freeze first column $('.qv-object-content-container').on('scroll', (t) => { $('.kpi-table').css('left', `${Math.round(t.target.scrollLeft)}px`); From b86806d4cd0db1cb081c3ac6d3f0769c67c72cb8 Mon Sep 17 00:00:00 2001 From: Kristoffer Lind Date: Thu, 14 Feb 2019 15:14:23 +0100 Subject: [PATCH 02/24] cleanup tooltips (resulted in whatever header was last hovered to be appended to each column header in xls) --- src/excel-export.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/excel-export.js b/src/excel-export.js index ff67e12..413f391 100644 --- a/src/excel-export.js +++ b/src/excel-export.js @@ -1,8 +1,20 @@ +function removeAllTooltips (node) { + const tooltips = node.querySelectorAll('.tooltip'); + [].forEach.call(tooltips, tooltip => { + if (tooltip.parentNode) { + tooltip.parentNode.removeChild(tooltip); + } + }); +} + function buildTableHTML (title, subtitle, footnote) { const titleHTML = `

${title}

`; const subtitleHTML = `

${subtitle}

`; const footnoteHTML = `

Note:${footnote}

`; const dataTableClone = document.querySelector('.data-table').cloneNode(true); + + removeAllTooltips(dataTableClone); + const tableHTML = ` Date: Sat, 16 Feb 2019 10:48:49 +0100 Subject: [PATCH 03/24] Update config.yml --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 040ea5c..c7735ea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,14 @@ jobs: - run: name: Install dependencies command: npm install + - run: + name: BlackDuck scan + command: curl -s https://blackducksoftware.github.io/hub-detect/hub-detect.sh | bash -s -- \ + --blackduck.url="https://qliktech.blackducksoftware.com" \ + --blackduck.trust.cert=true \ + --blackduck.username="svc-blackduck" \ + --blackduck.password=${svc_blackduck} \ + --detect.project.name="viz-bundle-qlik-smart-pivot" - run: name: Run tests command: npm run test-once From b65d1c51fcd5d0ee6219886d817ce7739caf14f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20=C3=85str=C3=B6m?= Date: Sat, 16 Feb 2019 10:49:46 +0100 Subject: [PATCH 04/24] Update qlik-smart-pivot.qext --- assets/qlik-smart-pivot.qext | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/qlik-smart-pivot.qext b/assets/qlik-smart-pivot.qext index c980707..4c1f96f 100644 --- a/assets/qlik-smart-pivot.qext +++ b/assets/qlik-smart-pivot.qext @@ -1,6 +1,6 @@ { - "name": "Smart pivot", - "description": "Formatted table for P&L reports.", + "name": "P&L pivot", + "description": "Profit & Loss reporting with color and font customizations.", "type": "visualization", "version": "X.Y.Z", "icon": "table", From 34477d7ef1d6494868794f1835b5c832be722fe1 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Mon, 18 Feb 2019 16:12:40 +0100 Subject: [PATCH 05/24] qlik font added to the fonts dropdown and was made a default value --- src/definition/formatted.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/definition/formatted.js b/src/definition/formatted.js index 3e1cce6..851b491 100644 --- a/src/definition/formatted.js +++ b/src/definition/formatted.js @@ -139,6 +139,10 @@ const formatted = { component: 'dropdown', label: 'FontFamily', options: [ + { + value: 'QlikView Sans', + label: 'QlikView Sans' + }, { value: 'Arial', label: 'Arial' @@ -164,7 +168,7 @@ const formatted = { label: 'Verdana' } ], - defaultValue: 'Calibri' + defaultValue: 'QlikView Sans' }, DataFontSize: { ref: 'lettersize', From ec140efc563a5548b35bf75854345da612b93672 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Mon, 18 Feb 2019 16:42:39 +0100 Subject: [PATCH 06/24] Text alignment property added --- src/data-table/data-cell.jsx | 14 ++++++++++++-- src/definition/formatted.js | 20 ++++++++++++++++++++ src/initialize-transformed.js | 3 ++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index adde657..deb216b 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -90,12 +90,22 @@ class DataCell extends React.PureComponent { if (styleBuilder.hasComments()) { formattedMeasurementValue = '.'; } + let textAlignment = 'Right'; + const textAlignmentProp = styling.options.textAlignment; + + if (textAlignmentProp === 1) { + textAlignment = 'Left'; + } else if (textAlignmentProp === 2) { + textAlignment = 'Center'; + } else { + textAlignment = 'Right'; + } let cellStyle = { fontFamily: styling.options.fontFamily, ...styleBuilder.getStyle(), paddingLeft: '4px', - textAlign: 'right' + textAlign: textAlignment }; const { semaphoreColors } = styling; @@ -109,7 +119,7 @@ class DataCell extends React.PureComponent { fontFamily: styling.options.fontFamily, fontSize: styleBuilder.getStyle().fontSize, paddingLeft: '4px', - textAlign: 'right' + textAlign: textAlignment }; } diff --git a/src/definition/formatted.js b/src/definition/formatted.js index 3e1cce6..ed9d110 100644 --- a/src/definition/formatted.js +++ b/src/definition/formatted.js @@ -183,6 +183,26 @@ const formatted = { ], defaultValue: 2 }, + textAlignment: { + ref: 'cellTextAlignment', + label: 'Cell Text alignment', + component: 'buttongroup', + options: [ + { + value: 1, + label: 'Left' + }, + { + value: 2, + label: 'Center' + }, + { + value: 3, + label: 'Right' + } + ], + defaultValue: 3 + }, ColumnWidthSlider: { type: 'number', component: 'slider', diff --git a/src/initialize-transformed.js b/src/initialize-transformed.js index f5e9585..42e38cc 100644 --- a/src/initialize-transformed.js +++ b/src/initialize-transformed.js @@ -279,7 +279,8 @@ async function initializeTransformed ({ $element, layout, component }) { backgroundColorOdd: colors[`vColLib${layout.ColorSchemaP}`], color: layout.BodyTextColorSchema, fontFamily: layout.FontFamily, - fontSizeAdjustment: getFontSizeAdjustment(layout.lettersize) + fontSizeAdjustment: getFontSizeAdjustment(layout.lettersize), + textAlignment: layout.cellTextAlignment }, semaphoreColors: { fieldsToApplyTo: { From bcb9d30237ed2ab95df6c26dcf00324e4f7a72c8 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Tue, 19 Feb 2019 14:55:50 +0100 Subject: [PATCH 07/24] sending the alignment value straight from props instead of numbers --- src/data-table/data-cell.jsx | 9 ++------- src/definition/formatted.js | 8 ++++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index deb216b..d176fc8 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -92,13 +92,8 @@ class DataCell extends React.PureComponent { } let textAlignment = 'Right'; const textAlignmentProp = styling.options.textAlignment; - - if (textAlignmentProp === 1) { - textAlignment = 'Left'; - } else if (textAlignmentProp === 2) { - textAlignment = 'Center'; - } else { - textAlignment = 'Right'; + if (textAlignmentProp) { + textAlignment = textAlignmentProp; } let cellStyle = { diff --git a/src/definition/formatted.js b/src/definition/formatted.js index ed9d110..2a41478 100644 --- a/src/definition/formatted.js +++ b/src/definition/formatted.js @@ -189,19 +189,19 @@ const formatted = { component: 'buttongroup', options: [ { - value: 1, + value: 'Left', label: 'Left' }, { - value: 2, + value: 'Center', label: 'Center' }, { - value: 3, + value: 'Right', label: 'Right' } ], - defaultValue: 3 + defaultValue: 'Right' }, ColumnWidthSlider: { type: 'number', From e70e76a401f6d008b35eb419788a442c446eb2ba Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Wed, 20 Feb 2019 15:44:36 +0100 Subject: [PATCH 08/24] small font size is set to be default and its value matched to Qlik defalut font size --- src/definition/formatted.js | 2 +- src/initialize-transformed.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/definition/formatted.js b/src/definition/formatted.js index 851b491..92647c4 100644 --- a/src/definition/formatted.js +++ b/src/definition/formatted.js @@ -185,7 +185,7 @@ const formatted = { label: 'Medium' } ], - defaultValue: 2 + defaultValue: 1 }, ColumnWidthSlider: { type: 'number', diff --git a/src/initialize-transformed.js b/src/initialize-transformed.js index f5e9585..6c31343 100644 --- a/src/initialize-transformed.js +++ b/src/initialize-transformed.js @@ -39,8 +39,8 @@ function getAlignment (option) { function getFontSizeAdjustment (option) { const fontSizeAdjustmentOptions = { - 1: -2, - 2: 0, + 1: -1, + 2: 1, 3: 2 }; From 35d4dde1181a4b330224a5001eb9dbf8a4b803d6 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Wed, 20 Feb 2019 15:50:54 +0100 Subject: [PATCH 09/24] exporting image and PDF enabled --- src/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/index.js b/src/index.js index 0ead03a..107b2f5 100644 --- a/src/index.js +++ b/src/index.js @@ -25,6 +25,11 @@ export default { qMeasures: [] } }, + support: { + export: true, + exportData: true, + snapshot: true + }, paint ($element, layout) { try { paint($element, layout, this); From 24edf1c6f4de5b834dcb3a9feb22454f465b6691 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Thu, 21 Feb 2019 12:02:42 +0100 Subject: [PATCH 10/24] values of text alignement property set to have lowercase --- src/definition/formatted.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/definition/formatted.js b/src/definition/formatted.js index 2a41478..5c9f266 100644 --- a/src/definition/formatted.js +++ b/src/definition/formatted.js @@ -189,19 +189,19 @@ const formatted = { component: 'buttongroup', options: [ { - value: 'Left', + value: 'left', label: 'Left' }, { - value: 'Center', + value: 'center', label: 'Center' }, { - value: 'Right', + value: 'right', label: 'Right' } ], - defaultValue: 'Right' + defaultValue: 'right' }, ColumnWidthSlider: { type: 'number', From 95e330a50d4fa518c61eec5c00b5c1353df3efdd Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Thu, 14 Feb 2019 13:02:59 +0100 Subject: [PATCH 11/24] tooltip added --- .eslintrc.js | 3 ++- src/data-table/data-cell.jsx | 50 ++++++++++++++++++++++++++++++++---- src/main.less | 30 ++++++++++++++++++++++ src/tooltip/index.jsx | 27 +++++++++++++++++++ 4 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 src/tooltip/index.jsx diff --git a/.eslintrc.js b/.eslintrc.js index 2328397..ec3a53b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -129,7 +129,8 @@ module.exports = { "react/jsx-no-literals": ["off"], "react/jsx-max-depth": ["off"], // rule throws exception in single-dimension-measure "react/jsx-filename-extension": ["warn"], - "react/prefer-stateless-function": ["warn"] + "react/prefer-stateless-function": ["warn"], + "react/no-set-state": ["warn"] }, extends: [ "eslint:all", diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index d176fc8..a9967a5 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { ApplyPreMask } from '../masking'; import { addSeparators } from '../utilities'; - +import Tooltip from '../tooltip/index.jsx'; function formatMeasurementValue (measurement, styling) { // TODO: measurement.name is a horrible propertyname, it's actually the column header const isColumnPercentageBased = measurement.parents.measurement.header.substring(0, 1) === '%'; @@ -61,14 +61,27 @@ function getSemaphoreColors (measurement, semaphoreColors) { } return semaphoreColors.statusColors.normal; } - -class DataCell extends React.PureComponent { +class DataCell extends React.Component { constructor (props) { super(props); - + this.state = { + bool: false, + mouseXPosition: 0, + mouseYPosition: 0 + }; + this.handleEnter = this.handleEnter.bind(this); + this.handleLeave = this.handleLeave.bind(this); this.handleSelect = this.handleSelect.bind(this); } + shouldComponentUpdate (nextProps, nextState) { + const { bool } = this.state; + if (bool === nextState.bool) { + return false; + } + return true; + } + handleSelect () { const { data: { meta: { dimensionCount } }, general: { allowFilteringByClick }, measurement, qlik } = this.props; const hasSecondDimension = dimensionCount > 1; @@ -83,8 +96,26 @@ class DataCell extends React.PureComponent { } } + handleEnter (event) { + this.setState({ bool: true, + mouseXPosition: event.clientX, + mouseYPosition: event.clientY }); + } + + handleLeave () { + this.setState({ bool: false }); + } + render () { - const { data, general, measurement, styleBuilder, styling } = this.props; + const { bool, mouseXPosition, mouseYPosition } = this.state; + const { + data, + general, + measurement, + styleBuilder, + styling + } = this.props; + const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; let formattedMeasurementValue = formatMeasurementValue(measurement, styling); if (styleBuilder.hasComments()) { @@ -128,9 +159,18 @@ class DataCell extends React.PureComponent { {formattedMeasurementValue} + {bool + ? + : null} ); } diff --git a/src/main.less b/src/main.less index 9f96728..87ea25e 100644 --- a/src/main.less +++ b/src/main.less @@ -2,6 +2,36 @@ @TableBorder: 1px solid #d3d3d3; @KpiTableWidth: 230px; + .edit-mode{ + pointer-events: none; + } + .tooltip-wrapper{ + position: fixed; + padding: 5px; + padding-top: 10px; + background-color: #404040; + z-index: 10; + pointer-events: none; + border-radius: 5px; + height: 30px; + width: auto; + opacity: .9; + >p{ + color: #fff; + } + } + + .tooltip-wrapper::after { + content: ""; + position: absolute; + bottom: -10px; + left: 50%; + border-width: 10px 10px 0; + border-style: solid; + border-color: #404040 transparent; + margin-left: -10px; + pointer-events: none; + } ._cell(@Width: 50px) { min-width: @Width!important; max-width: @Width!important; diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx new file mode 100644 index 0000000..61751c5 --- /dev/null +++ b/src/tooltip/index.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +const getPos = () => { + console.log(window.pageXOffset); + return { + left: window.pageXOffset, + top: window.pageYOffset + }; + +}; + +const Tooltip = ({ data, xPosition, yPosition }) => ( +
+

+ {data} +

+
+); +Tooltip.propTypes = { + data: PropTypes.string.isRequired, + xPosition: PropTypes.number, + yPosition: PropTypes.number +}; +export default Tooltip; From aeccbf5d17fc044205f7f29986b916e87006e1c9 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Thu, 14 Feb 2019 14:04:15 +0100 Subject: [PATCH 12/24] tooltip disabled in edit state --- src/data-table/data-cell.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index a9967a5..f4d0f15 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -113,9 +113,11 @@ class DataCell extends React.Component { general, measurement, styleBuilder, - styling + styling, + qlik } = this.props; + const inEditState = qlik.inEditState(); const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; let formattedMeasurementValue = formatMeasurementValue(measurement, styling); if (styleBuilder.hasComments()) { @@ -164,7 +166,7 @@ class DataCell extends React.Component { style={cellStyle} > {formattedMeasurementValue} - {bool + {bool && !inEditState ? Date: Fri, 15 Feb 2019 08:53:35 +0100 Subject: [PATCH 13/24] mind width set to tooltip text inside it is center aligned --- src/main.less | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.less b/src/main.less index 87ea25e..1da5609 100644 --- a/src/main.less +++ b/src/main.less @@ -6,9 +6,10 @@ pointer-events: none; } .tooltip-wrapper{ + min-width: 25px; position: fixed; padding: 5px; - padding-top: 10px; + padding-top: 15px; background-color: #404040; z-index: 10; pointer-events: none; @@ -16,6 +17,7 @@ height: 30px; width: auto; opacity: .9; + text-align: center; >p{ color: #fff; } From 521d5086043774a40a681c0a214e13378576193b Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 08:54:11 +0100 Subject: [PATCH 14/24] commented jqeury from paint.js for tooltip --- src/paint.jsx | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/paint.jsx b/src/paint.jsx index e2bef20..620218f 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -60,25 +60,29 @@ export default async function paint ($element, layout, component) { }); // TODO: fixing tooltips has a seperate issue, make sure to remove this as part of that issue - $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).hover(function () { - $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(500) - .show(0); - $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).children(`[tid="${layout.qInfo.qId}"] .tooltip`) - .remove(); + // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).hover(function () { + // $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(500) + // .show(0); + // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).children(`[tid="${layout.qInfo.qId}"] .tooltip`) + // .remove(); - const element = $(this); - const offset = element.offset(); - const toolTip = $('
'); + // const element = $(this); + // const offset = element.offset(); + // const toolTip = $('
'); - toolTip.css({ - left: offset.left, - top: offset.top - }); + // toolTip.css({ + // left: offset.left, + // top: offset.top + // }); - toolTip.text(element.text()); - $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).append(toolTip); - }, () => { - $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(0) - .hide(0); - }); + // toolTip.text(element.text()); + // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).append(toolTip); + // }, () => { + // $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(0) + // .hide(0); + // }); + + // TODO: excel export is broken in most browsers, fixing it has an issue of it's own (leaving it disabled for now) + // import { enableExcelExport } from './excel-export'; + // enableExcelExport(layout, html); } From 6994bf51a3725c60d09ffaf8055701c926a94275 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 08:55:13 +0100 Subject: [PATCH 15/24] showTooltip boolean changed name skipping values that are header rows --- src/data-table/data-cell.jsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index f4d0f15..e39c1ac 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -65,7 +65,7 @@ class DataCell extends React.Component { constructor (props) { super(props); this.state = { - bool: false, + showTooltip: false, mouseXPosition: 0, mouseYPosition: 0 }; @@ -75,8 +75,8 @@ class DataCell extends React.Component { } shouldComponentUpdate (nextProps, nextState) { - const { bool } = this.state; - if (bool === nextState.bool) { + const { showTooltip } = this.state; + if (showTooltip === nextState.showTooltip) { return false; } return true; @@ -97,17 +97,17 @@ class DataCell extends React.Component { } handleEnter (event) { - this.setState({ bool: true, + this.setState({ showTooltip: true, mouseXPosition: event.clientX, mouseYPosition: event.clientY }); } handleLeave () { - this.setState({ bool: false }); + this.setState({ showTooltip: false }); } render () { - const { bool, mouseXPosition, mouseYPosition } = this.state; + const { showTooltip, mouseXPosition, mouseYPosition } = this.state; const { data, general, @@ -166,7 +166,7 @@ class DataCell extends React.Component { style={cellStyle} > {formattedMeasurementValue} - {bool && !inEditState + {showTooltip && !inEditState && formattedMeasurementValue !== '.' ? Date: Fri, 15 Feb 2019 08:56:02 +0100 Subject: [PATCH 16/24] tooltip added to column header comopnent changed to normal component to hold state in it --- src/headers-table/column-header.jsx | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/headers-table/column-header.jsx b/src/headers-table/column-header.jsx index d50d666..73f0fdd 100644 --- a/src/headers-table/column-header.jsx +++ b/src/headers-table/column-header.jsx @@ -1,20 +1,49 @@ import React from 'react'; import PropTypes from 'prop-types'; +import Tooltip from '../tooltip/index.jsx'; -class ColumnHeader extends React.PureComponent { +class ColumnHeader extends React.Component { constructor (props) { super(props); - + this.state = { + showTooltip: false, + mouseXPosition: 0, + mouseYPosition: 0 + }; + this.handleEnter = this.handleEnter.bind(this); + this.handleLeave = this.handleLeave.bind(this); this.handleSelect = this.handleSelect.bind(this); } + shouldComponentUpdate (nextProps, nextState) { + const { showTooltip } = this.state; + if (showTooltip === nextState.showTooltip) { + return false; + } + return true; + } + handleSelect () { const { entry, qlik } = this.props; qlik.backendApi.selectValues(1, [entry.elementNumber], true); } + handleEnter (event) { + console.log(event.clientX); + this.setState({ showTooltip: true, + mouseXPosition: event.clientX, + mouseYPosition: event.clientY }); + } + + handleLeave () { + this.setState({ showTooltip: false }); + } + render () { - const { baseCSS, cellSuffix, colSpan, entry, styling } = this.props; + const { baseCSS, cellSuffix, colSpan, entry, styling, qlik } = this.props; + const { showTooltip, mouseXPosition, mouseYPosition } = this.state; + const inEditState = qlik.inEditState(); + const style = { ...baseCSS, fontSize: `${14 + styling.headerOptions.fontSizeAdjustment} px`, @@ -27,9 +56,18 @@ class ColumnHeader extends React.PureComponent { className={`grid-cells2${cellSuffix}`} colSpan={colSpan} onClick={this.handleSelect} + onMouseOut={this.handleLeave} + onMouseOver={this.handleEnter} style={style} > {entry.displayValue} + {showTooltip && !inEditState + ? + : null} ); } From 906a11c6b4c75baa108101875602c53a72c3dbe1 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 08:56:26 +0100 Subject: [PATCH 17/24] tooltip component cleaned --- src/tooltip/index.jsx | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index 61751c5..53e004d 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -1,18 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -const getPos = () => { - console.log(window.pageXOffset); - return { - left: window.pageXOffset, - top: window.pageYOffset - }; - -}; const Tooltip = ({ data, xPosition, yPosition }) => (

{data} From da57204c413c207ddd98b27dea5efe64092e4446 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 09:26:16 +0100 Subject: [PATCH 18/24] console log removed --- src/headers-table/column-header.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/headers-table/column-header.jsx b/src/headers-table/column-header.jsx index 73f0fdd..d3bdbbb 100644 --- a/src/headers-table/column-header.jsx +++ b/src/headers-table/column-header.jsx @@ -29,7 +29,6 @@ class ColumnHeader extends React.Component { } handleEnter (event) { - console.log(event.clientX); this.setState({ showTooltip: true, mouseXPosition: event.clientX, mouseYPosition: event.clientY }); From 98678d4a138c7d20f597f7d3c7cb876d71bca5c8 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 09:32:55 +0100 Subject: [PATCH 19/24] jQuery commented code deleted --- src/paint.jsx | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/paint.jsx b/src/paint.jsx index 620218f..5428149 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -59,29 +59,6 @@ export default async function paint ($element, layout, component) { $(`[tid="${layout.qInfo.qId}"] .kpi-table`).css('left', `${Math.round(t.target.scrollLeft)}px`); }); - // TODO: fixing tooltips has a seperate issue, make sure to remove this as part of that issue - // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).hover(function () { - // $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(500) - // .show(0); - // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).children(`[tid="${layout.qInfo.qId}"] .tooltip`) - // .remove(); - - // const element = $(this); - // const offset = element.offset(); - // const toolTip = $('

'); - - // toolTip.css({ - // left: offset.left, - // top: offset.top - // }); - - // toolTip.text(element.text()); - // $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).append(toolTip); - // }, () => { - // $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(0) - // .hide(0); - // }); - // TODO: excel export is broken in most browsers, fixing it has an issue of it's own (leaving it disabled for now) // import { enableExcelExport } from './excel-export'; // enableExcelExport(layout, html); From 4520d6a48ae1aba65705a163e0503feb5cb495ee Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 09:56:32 +0100 Subject: [PATCH 20/24] handling tooltip logic within it --- src/data-table/data-cell.jsx | 20 +++++++------------ src/headers-table/column-header.jsx | 20 +++++++------------ src/tooltip/index.jsx | 30 +++++++++++++++-------------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index e39c1ac..571a299 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -65,9 +65,7 @@ class DataCell extends React.Component { constructor (props) { super(props); this.state = { - showTooltip: false, - mouseXPosition: 0, - mouseYPosition: 0 + showTooltip: false }; this.handleEnter = this.handleEnter.bind(this); this.handleLeave = this.handleLeave.bind(this); @@ -96,10 +94,8 @@ class DataCell extends React.Component { } } - handleEnter (event) { - this.setState({ showTooltip: true, - mouseXPosition: event.clientX, - mouseYPosition: event.clientY }); + handleEnter () { + this.setState({ showTooltip: true }); } handleLeave () { @@ -107,7 +103,7 @@ class DataCell extends React.Component { } render () { - const { showTooltip, mouseXPosition, mouseYPosition } = this.state; + const { showTooltip } = this.state; const { data, general, @@ -168,11 +164,9 @@ class DataCell extends React.Component { {formattedMeasurementValue} {showTooltip && !inEditState && formattedMeasurementValue !== '.' ? - : null} + + {formattedMeasurementValue} + : null} ); } diff --git a/src/headers-table/column-header.jsx b/src/headers-table/column-header.jsx index d3bdbbb..da9120c 100644 --- a/src/headers-table/column-header.jsx +++ b/src/headers-table/column-header.jsx @@ -6,9 +6,7 @@ class ColumnHeader extends React.Component { constructor (props) { super(props); this.state = { - showTooltip: false, - mouseXPosition: 0, - mouseYPosition: 0 + showTooltip: false }; this.handleEnter = this.handleEnter.bind(this); this.handleLeave = this.handleLeave.bind(this); @@ -28,10 +26,8 @@ class ColumnHeader extends React.Component { qlik.backendApi.selectValues(1, [entry.elementNumber], true); } - handleEnter (event) { - this.setState({ showTooltip: true, - mouseXPosition: event.clientX, - mouseYPosition: event.clientY }); + handleEnter () { + this.setState({ showTooltip: true }); } handleLeave () { @@ -40,7 +36,7 @@ class ColumnHeader extends React.Component { render () { const { baseCSS, cellSuffix, colSpan, entry, styling, qlik } = this.props; - const { showTooltip, mouseXPosition, mouseYPosition } = this.state; + const { showTooltip } = this.state; const inEditState = qlik.inEditState(); const style = { @@ -62,11 +58,9 @@ class ColumnHeader extends React.Component { {entry.displayValue} {showTooltip && !inEditState ? - : null} + + {entry.displayValue} + : null} ); } diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index 53e004d..1d920e5 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -1,20 +1,22 @@ import React from 'react'; import PropTypes from 'prop-types'; -const Tooltip = ({ data, xPosition, yPosition }) => ( -
-

- {data} -

-
-); +const Tooltip = ({ children }) => { + const xPosition = event.clientX; + const yPosition = event.clientY; + return ( +
+

+ {children} +

+
+ ); +}; Tooltip.propTypes = { - data: PropTypes.string.isRequired, - xPosition: PropTypes.number, - yPosition: PropTypes.number + children: PropTypes.string.isRequired }; export default Tooltip; From 79b89a3b2557ff0aca9c62cd480b4e4a18bb8cf1 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Fri, 15 Feb 2019 11:33:43 +0100 Subject: [PATCH 21/24] all logic for tooltip has been moved to it's component data-cell & column-header components reseted to pure ones --- src/data-table/data-cell.jsx | 38 +++------------ src/headers-table/column-header.jsx | 38 +++------------ src/tooltip/index.jsx | 74 +++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 77 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index 571a299..4266827 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -61,25 +61,12 @@ function getSemaphoreColors (measurement, semaphoreColors) { } return semaphoreColors.statusColors.normal; } -class DataCell extends React.Component { +class DataCell extends React.PureComponent { constructor (props) { super(props); - this.state = { - showTooltip: false - }; - this.handleEnter = this.handleEnter.bind(this); - this.handleLeave = this.handleLeave.bind(this); this.handleSelect = this.handleSelect.bind(this); } - shouldComponentUpdate (nextProps, nextState) { - const { showTooltip } = this.state; - if (showTooltip === nextState.showTooltip) { - return false; - } - return true; - } - handleSelect () { const { data: { meta: { dimensionCount } }, general: { allowFilteringByClick }, measurement, qlik } = this.props; const hasSecondDimension = dimensionCount > 1; @@ -94,16 +81,7 @@ class DataCell extends React.Component { } } - handleEnter () { - this.setState({ showTooltip: true }); - } - - handleLeave () { - this.setState({ showTooltip: false }); - } - render () { - const { showTooltip } = this.state; const { data, general, @@ -157,16 +135,14 @@ class DataCell extends React.Component { - {formattedMeasurementValue} - {showTooltip && !inEditState && formattedMeasurementValue !== '.' - ? - - {formattedMeasurementValue} - : null} + + {formattedMeasurementValue} + ); } diff --git a/src/headers-table/column-header.jsx b/src/headers-table/column-header.jsx index da9120c..e698a82 100644 --- a/src/headers-table/column-header.jsx +++ b/src/headers-table/column-header.jsx @@ -2,41 +2,19 @@ import React from 'react'; import PropTypes from 'prop-types'; import Tooltip from '../tooltip/index.jsx'; -class ColumnHeader extends React.Component { +class ColumnHeader extends React.PureComponent { constructor (props) { super(props); - this.state = { - showTooltip: false - }; - this.handleEnter = this.handleEnter.bind(this); - this.handleLeave = this.handleLeave.bind(this); this.handleSelect = this.handleSelect.bind(this); } - shouldComponentUpdate (nextProps, nextState) { - const { showTooltip } = this.state; - if (showTooltip === nextState.showTooltip) { - return false; - } - return true; - } - handleSelect () { const { entry, qlik } = this.props; qlik.backendApi.selectValues(1, [entry.elementNumber], true); } - handleEnter () { - this.setState({ showTooltip: true }); - } - - handleLeave () { - this.setState({ showTooltip: false }); - } - render () { const { baseCSS, cellSuffix, colSpan, entry, styling, qlik } = this.props; - const { showTooltip } = this.state; const inEditState = qlik.inEditState(); const style = { @@ -51,16 +29,14 @@ class ColumnHeader extends React.Component { className={`grid-cells2${cellSuffix}`} colSpan={colSpan} onClick={this.handleSelect} - onMouseOut={this.handleLeave} - onMouseOver={this.handleEnter} style={style} > - {entry.displayValue} - {showTooltip && !inEditState - ? - - {entry.displayValue} - : null} + + {entry.displayValue} + ); } diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index 1d920e5..060cabe 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -1,22 +1,66 @@ import React from 'react'; import PropTypes from 'prop-types'; +class Tooltip extends React.Component { + constructor (props) { + super(props); + this.state = { + showTooltip: false, + xPosition: 0, + yPosition: 0 + }; + this.handleRenderTooltip = this.handleRenderTooltip.bind(this); + } -const Tooltip = ({ children }) => { - const xPosition = event.clientX; - const yPosition = event.clientY; - return ( -
-

+ shouldComponentUpdate (nextProps, nextState) { + const { showTooltip } = this.state; + if (nextState.showTooltip === showTooltip) { + return false; + } + return true; + } + + handleRenderTooltip (event) { + const { showTooltip } = this.state; + const xPosition = event.clientX; + const yPosition = event.clientY; + this.setState({ showTooltip: !showTooltip, + xPosition, + yPosition }); + } + + render () { + const { children, tooltipText, isTooltipActive } = this.props; + const { showTooltip, xPosition, yPosition } = this.state; + + const xPositionOffset = 20; + const yPositionOffset = 75; + return ( +

{children} -

-
- ); -}; + + {showTooltip && isTooltipActive + ? ( +
+

+ {tooltipText} +

+
+ ) : null} +
+ ); + } +} + Tooltip.propTypes = { - children: PropTypes.string.isRequired + children: PropTypes.string.isRequired, + isTooltipActive: PropTypes.bool.isRequired, + tooltipText: PropTypes.string.isRequired }; export default Tooltip; From 530f0919f13ac27cab7b439d54d8fd8b971d7d18 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Tue, 19 Feb 2019 15:41:30 +0100 Subject: [PATCH 22/24] tooltip positioning tweaked --- src/main.less | 13 ++++++++++--- src/tooltip/index.jsx | 18 ++++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main.less b/src/main.less index 1da5609..ec82ceb 100644 --- a/src/main.less +++ b/src/main.less @@ -7,17 +7,21 @@ } .tooltip-wrapper{ min-width: 25px; - position: fixed; + position: absolute; padding: 5px; padding-top: 15px; background-color: #404040; - z-index: 10; + z-index: 100; pointer-events: none; border-radius: 5px; height: 30px; width: auto; opacity: .9; text-align: center; + bottom: 0; + left: 0; + right: 0; + transform: translate(0,-70%); >p{ color: #fff; } @@ -163,7 +167,10 @@ background-color: #808080 !important; color: #ffffff; } - + .grid-cells{ + position: relative; + overflow: visible; + } .grid-cells-header { padding: 0px; } diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index 060cabe..a131a31 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -4,9 +4,7 @@ class Tooltip extends React.Component { constructor (props) { super(props); this.state = { - showTooltip: false, - xPosition: 0, - yPosition: 0 + showTooltip: false }; this.handleRenderTooltip = this.handleRenderTooltip.bind(this); } @@ -19,21 +17,15 @@ class Tooltip extends React.Component { return true; } - handleRenderTooltip (event) { + handleRenderTooltip () { const { showTooltip } = this.state; - const xPosition = event.clientX; - const yPosition = event.clientY; - this.setState({ showTooltip: !showTooltip, - xPosition, - yPosition }); + this.setState({ showTooltip: !showTooltip }); } render () { const { children, tooltipText, isTooltipActive } = this.props; - const { showTooltip, xPosition, yPosition } = this.state; + const { showTooltip } = this.state; - const xPositionOffset = 20; - const yPositionOffset = 75; return (

{tooltipText} From 88ad73bd412ebbbd628f85454dadfc551d74e0c7 Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Tue, 19 Feb 2019 16:58:39 +0100 Subject: [PATCH 23/24] tooltip position now follow the mouse --- .eslintrc.js | 2 +- src/main.less | 6 +----- src/tooltip/index.jsx | 12 ++++++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ec3a53b..1af18c4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -116,7 +116,7 @@ module.exports = { "max-params": ["warn"], "brace-style": ["warn", "1tbs", { "allowSingleLine": true }], "prefer-const": ["warn"], - + "class-methods-use-this":["warn"], // plugin:react "react/jsx-indent": ["warn", 2], "react/jsx-indent-props": ["warn", 2], diff --git a/src/main.less b/src/main.less index ec82ceb..1cfca0f 100644 --- a/src/main.less +++ b/src/main.less @@ -7,7 +7,7 @@ } .tooltip-wrapper{ min-width: 25px; - position: absolute; + position: fixed; padding: 5px; padding-top: 15px; background-color: #404040; @@ -18,10 +18,6 @@ width: auto; opacity: .9; text-align: center; - bottom: 0; - left: 0; - right: 0; - transform: translate(0,-70%); >p{ color: #fff; } diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index a131a31..c156c80 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -7,6 +7,7 @@ class Tooltip extends React.Component { showTooltip: false }; this.handleRenderTooltip = this.handleRenderTooltip.bind(this); + this.handleCalculateTooltipPosition = this.handleCalculateTooltipPosition.bind(this); } shouldComponentUpdate (nextProps, nextState) { @@ -22,12 +23,23 @@ class Tooltip extends React.Component { this.setState({ showTooltip: !showTooltip }); } + handleCalculateTooltipPosition (event) { + const tooltipClassName = 'tooltip-wrapper'; + let tooltip = document.getElementsByClassName(tooltipClassName); + const xPositionOffset = 25; + const yPositionOffset = 65; + + tooltip[0].style.left = event.clientX - xPositionOffset + 'px'; + tooltip[0].style.top = event.clientY - yPositionOffset + 'px'; + } + render () { const { children, tooltipText, isTooltipActive } = this.props; const { showTooltip } = this.state; return (

From bdf231f88d114ad0756ca4a1567d44c99aea2f8a Mon Sep 17 00:00:00 2001 From: ahmed-Bazzara Date: Thu, 21 Feb 2019 12:29:16 +0100 Subject: [PATCH 24/24] code enhancements --- src/data-table/data-cell.jsx | 5 +---- src/main.less | 1 + src/tooltip/index.jsx | 25 +++++++++++-------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index 4266827..3a50bc0 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -87,11 +87,9 @@ class DataCell extends React.PureComponent { general, measurement, styleBuilder, - styling, - qlik + styling } = this.props; - const inEditState = qlik.inEditState(); const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; let formattedMeasurementValue = formatMeasurementValue(measurement, styling); if (styleBuilder.hasComments()) { @@ -138,7 +136,6 @@ class DataCell extends React.PureComponent { style={cellStyle} > {formattedMeasurementValue} diff --git a/src/main.less b/src/main.less index 1cfca0f..54cb114 100644 --- a/src/main.less +++ b/src/main.less @@ -18,6 +18,7 @@ width: auto; opacity: .9; text-align: center; + transform: translate(-50%,-110%); >p{ color: #fff; } diff --git a/src/tooltip/index.jsx b/src/tooltip/index.jsx index c156c80..336c6a1 100644 --- a/src/tooltip/index.jsx +++ b/src/tooltip/index.jsx @@ -1,5 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; + +const handleCalculateTooltipPosition = (event) => { + const tooltipClassName = 'tooltip-wrapper'; + const tooltip = document.getElementsByClassName(tooltipClassName); + + tooltip[0].style.left = event.clientX + 'px'; + tooltip[0].style.top = event.clientY + 'px'; +}; class Tooltip extends React.Component { constructor (props) { super(props); @@ -7,7 +15,6 @@ class Tooltip extends React.Component { showTooltip: false }; this.handleRenderTooltip = this.handleRenderTooltip.bind(this); - this.handleCalculateTooltipPosition = this.handleCalculateTooltipPosition.bind(this); } shouldComponentUpdate (nextProps, nextState) { @@ -23,29 +30,20 @@ class Tooltip extends React.Component { this.setState({ showTooltip: !showTooltip }); } - handleCalculateTooltipPosition (event) { - const tooltipClassName = 'tooltip-wrapper'; - let tooltip = document.getElementsByClassName(tooltipClassName); - const xPositionOffset = 25; - const yPositionOffset = 65; - - tooltip[0].style.left = event.clientX - xPositionOffset + 'px'; - tooltip[0].style.top = event.clientY - yPositionOffset + 'px'; - } render () { - const { children, tooltipText, isTooltipActive } = this.props; + const { children, tooltipText } = this.props; const { showTooltip } = this.state; return (
{children} - {showTooltip && isTooltipActive + {showTooltip ? (