2

I want to add "..." or ">>" icon after 100 characters in my each HTML table column. Clicking on this icon will render the content in a simple pop-up multi-line box. 'Esc' or clicking on 'X' closes the box.

I have created a table dynamically using d3.js parsing CSV file. Below are my HTML and JavaScript

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
 <title>TableView</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
 <div id="table-wrapper">
   <div id="table-scroll">
         <!-- Table goes here -->
   </div>
 </div>
 <script src="http://d3js.org/d3.v3.min.js"></script>
 <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
 </body>
 </html>

 app.js

 d3.csv("js/tweetBlog.csv", function(error, data) {
 var sortAscending = true;
 var table = d3.select('#table-wrapper').select('#table-scroll').append('table');
var titles = d3.keys(data[0]);
var headers = table.append('thead').append('tr').selectAll('th')
              .data(titles).enter().append('th')
                       .text(function (d) {
                            return d;
                        })
                       .on('click', function (d) {
                           headers.attr('class', 'header');

                           if (sortAscending) {
                             rows.sort(function(a, b) { return b[d] < a[d]; });
                             sortAscending = false;
                             this.className = 'aes';
                           } else {
                             rows.sort(function(a, b) { return b[d] > a[d]; });
                             sortAscending = true;
                             this.className = 'des';
                           }

                       });

      var rows = table.append('tbody').selectAll('tr')
                   .data(data).enter().append('tr');
      rows.selectAll('td')
        .data(function (d) {
            return titles.map(function (k) {
                return { 'value': d[k], 'name': k};
            });
        }).enter()
        .append('td')
        .attr('data-th', function (d) {
            return d.name;
        })
        .text(function (d) {
            return d.value;
        });
  });
Bengi Besçeli
  • 3,638
  • 12
  • 53
  • 87
Aakash Takale
  • 115
  • 1
  • 13
  • Are you just [looking for the style](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow) `text-overflow: ellipsis;`? – Mark Mar 02 '17 at 00:47
  • Have a look at http://stackoverflow.com/questions/5474871/html-how-can-i-show-tooltip-only-when-ellipsis-is-activated – NineBerry Mar 02 '17 at 00:56
  • I tried "text-overflow: ellipsis" but it simply hides the content. I want to perform an action by clicking "..." or ">>" icon. – Aakash Takale Mar 02 '17 at 02:41
  • NineBerry I did look at the StackOverflow question you mentioned, but it is using jQuery and that is not exactly what I am looking for. Thanks. – Aakash Takale Mar 02 '17 at 02:45
  • 1
    AakashTakale most (if not all?) of the jQuery in the answers from the question linked by @NineBerry all seems to be methods that are just shorthand for native JS, so I would think it would be quite easy to convert them to native JS and use them; I'm just saying that if those techniques could work for you, you shouldn't immediately dismiss them only because they are jQuery – chiliNUT Mar 02 '17 at 02:58

1 Answers1

2

If you are creating your table in d3, then it should be pretty straight forward to:

a. Limit cell contents to a certain character length and add the required "click to view" symbol. Something like the following when appending your table cells:

   .html(function(d) { 
      if (d.length < 20) { return d; }
      else { return d.substring(0,19) + "<span class='expand'>>></span>" }

b. Add an event listener to each symbol that shows the expanded content (and a corresponding one to close the content). Something like the following:

d3.selectAll('.expand')
   .on('click',function() { 
      // show tooltip
})

I've appended an example using regular text but it should be the same method to apply it to a table cell with d3. While I haven't used an [x] symbol to close the box, simply clicking the tooltip will close it (you could add the [x] to the tooltip and assign the close listener to it easily).

var data = [
"This is text that much too verbose and thus is cut off",
"This text is too long and therefore is also cut off",
"This text is short"
];

var tooltip = d3.select("body").append("div") 
    .attr("class", "tooltip")    
    .style("opacity", 0);

var div = d3.select('body').append('div');

var text = div.selectAll('p')
   .data(data)
   .enter()
   .append('p')
   .html(function(d) { 
      if (d.length < 20) { return d; }
      else { return d.substring(0,19) + "<span class='expand'>>></span>" }
   })
   
var expand = d3.selectAll('.expand')
   .on('click',function() { 
      tooltip.html(d3.select(this.parentNode).data()) 
       .style("opacity", .9)
       .style("left", (d3.event.pageX) + "px")  
       .style("top", (d3.event.pageY) + "px"); 
   })
   
d3.selectAll('.tooltip')
   .on('click', function() {
      d3.select(this).style('opacity',0);
   })
div.tooltip { 
    position: absolute;   
    text-align: center;   
    width: 50px;
    height: auto;     
    padding: 2px;    
    font: 12px sans-serif;  
    background: #d3d3d3;   
    pointer-events: all;
    padding: 10px;
    border: 1px dotted black;
}

.expand {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>

The tooltip I used comes from d3noob's tooltip bl.ock.

Andrew Reid
  • 37,021
  • 7
  • 64
  • 83