6
\$\begingroup\$

I recently ran in to a problem with the presentation of data related to a graph. Each series of data has values that define the 'curve'. There can be a lot of these values, and I decided that there was not enough space in the 'legend' to include all the details for the curve. I decided to have a 'details' area, and users could select a curve/series, and the details would be displayed in an area under the graph. This is because there would otherwise be too much data to show in the legend.

The details consist of 4 items, a colour "patch", a series name, the series accuracy, and the data points in the series. A table is what I chose to display these values in.

I want the details area to occupy the base of the screen underneath the graph, and to grow/shrink as the chart grows/shrinks. The last column in the table, the data points, are the largest part of the data, and would 'flood' the area. I want to make it possible to select all the data, but not necessarily make it all visible, a scrolling system would be fine.

In essence, I have this:

Chart with detail

What I want reviewed in this question, though, is just the dynamic nature of the 4-column, 1-row table at the bottom, this:

Details table

Although the table scales well when the screen-size changes, I believe there must be a better way to implement it.

Here is my extraction of the relevant code, with some test data:

.container {
    width: 80%;
    margin: 0 auto;
    border: 2px solid black;
}

#dummy {
    width: 100%;
    background-color: lightgreen;
}

.details {
    width: 100%;
    border-collapse: collapse;
}

.details td {
    border: 1px black solid;
    padding: 3px;
}

.details td:last-child {
    width: 100%;
    background-color: lightblue;
    padding-right: 7px;
}

.details td:last-child input {
    width: 100%;
}
    <div id="dummy" >text to show where a graph would be</div>
    <hr>

    Manual visualization

    <table class="details">
      <tr>
        <td>
          <label for="seriesName">Series</label>
          <input id="seriesName" type="text" size="15" readonly="readonly" value="Manual Sizing" >
        </td>
        <td>
          <label for="seriesRSquare">RSquared</label>
          <input id="seriesRSquare" type="text" size="10" readonly="readonly" value="0.98765432" >
        </td>
        <td>
          <label for="seriesDetail">Description</label>
          <input id="seriesDetail" type="text" readonly="readonly" 
            value="[1,23],[2,20],[4,20],[8,21],[16,23],[32,22],[64,26],[128,28],[256,41],[512,55],[1024,81],[2048,136],[4096,244],[8192,474],[16384,959],[32768,1987],[65536,3613],[131072,6957],[262144,14250],[524288,28215],[1048576,55882],[2097152,116210],[3145728,175000],[4194304,229976],[5242880,291501],[6291456,347649],[7340032,399349],[8388608,485512]">
        </td>
      </tr>
    </table>

My specific concerns for this are:

  1. The 'input' in the last column has width: 100% because otherwise it is too small. The input area unfortunately extends past the td border though, so I have had to add a manual padding of 7 px to the right side of the td to make it work. This seems counter-intuitive
  2. the use of read-only input members allows the data to be shown, and scrolled-through, if needed, but is it the 'right way'?

I am open to any suggestions on how to best present this data.

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

The 7px padding issue can be solved by adding box-sizing: border-box to the input. That'll make the input's 100% width include the input's border and padding.

As for using a read-only input, I'd say that's a fine solution - at least for the data. Besides scrolling without requiring a scrollbar, it also let's you use a select all command, without it selecting the entire page.

The series name and r2 stuff doesn't need to be labels and inputs, though. They can be spans if you want to style their values, but basically I'd suggest something like this:

<td>
  Series
  <br>
  Manual Sizing
</td>

The trick, then, is to add the following to .details td:

width: 1%;
white-space: nowrap;

This will prevent the text wrapping on the space in "Manual Sizing", but the explicit break tag is still respected. And, because the cell is set to 1% width (or some other low, low value), it'll shrink to its smallest size, leaving more room for the data.

Again, if you use spans to separately style name and value within the two cells, you can apply the nowrap rule to the spans alone, while the 1% width can remain on the enclosing <td> to squish it.

In the end I get:

#dummy {
    width: 100%;
    background-color: lightgreen;
}

.details {
    width: 100%;
    border-collapse: collapse;
}

.details td {
    border: 1px black solid;
    padding: 3px;
    width: 1%;
    white-space: nowrap;
}

.details td:last-child {
    width: 100%;
    background-color: lightblue;
}

.details td:last-child input {
    box-sizing: border-box;
    width: 100%;
}
    <div id="dummy" >text to show where a graph would be</div>

    <hr>

    Manual visualization

    <table class="details">
      <tr>
        <td>
          Series
          <br>
          Manual Sizing
        </td>
        <td>
          RSquared
          <br>
          0.98765432
        </td>
        <td>
          Description
          <br>
          <input id="seriesDetail" type="text" readonly 
            value="[1,23],[2,20],[4,20],[8,21],[16,23],[32,22],[64,26],[128,28],[256,41],[512,55],[1024,81],[2048,136],[4096,244],[8192,474],[16384,959],[32768,1987],[65536,3613],[131072,6957],[262144,14250],[524288,28215],[1048576,55882],[2097152,116210],[3145728,175000],[4194304,229976],[5242880,291501],[6291456,347649],[7340032,399349],[8388608,485512]">
        </td>
      </tr>
    </table>

I've dropped the <label> tag for the data input, but that's just me.

Lastly, the readonly attribute doesn't need to have a value; it just needs to be "mentioned", so to speak. It's presence is its value. Giving it a value is fine too, of course. Just thought I'd mention it.

The downside of squishing the cells is of course that the layout will shift a little for different content. E.g. a longer series name will push things around.

Again, if you use a span, you can add something like this to limit its size:

display: inline-block; /* allows the span to respect a max-width */
max-width: 100px; /* or something */
overflow: hidden;
text-overflow: ellipsis;

That'll truncate the text to fit 100px (e.g. you'd get "Manual S…" or something).

The gotcha is that the text-overflow literally chops off some of the text, so it's no longer selectable. On my screen the snippet below shows the series name as "Manual…", while selecting it and copying only copies "Manual" (leaving out both the truncated text, and the ellipsis that replaced it).

.details {
    width: 100%;
    border-collapse: collapse;
}

.details td {
    border: 1px black solid;
    padding: 3px;
    width: 1%;
    white-space: nowrap;
}

.details td:last-child {
    width: 100%;
    background-color: lightblue;
}

.details td:last-child input {
    box-sizing: border-box;
    width: 100%;
}

.details td span {
    display: inline-block;
    max-width: 64px;
    overflow: hidden;
    text-overflow: ellipsis;
}
    <table class="details">
      <tr>
        <td>
          Series
          <br>
          <span>Manual Sizing</span>
        </td>
        <td>
          RSquared
          <br>
          <span>0.98765432</span>
        </td>
        <td>
          Description
          <br>
          <input id="seriesDetail" type="text" readonly 
            value="[1,23],[2,20],[4,20],[8,21],[16,23],[32,22],[64,26],[128,28],[256,41],[512,55],[1024,81],[2048,136],[4096,244],[8192,474],[16384,959],[32768,1987],[65536,3613],[131072,6957],[262144,14250],[524288,28215],[1048576,55882],[2097152,116210],[3145728,175000],[4194304,229976],[5242880,291501],[6291456,347649],[7340032,399349],[8388608,485512]">
        </td>
      </tr>
    </table>


Edit: Thinking about it some more, you probably should go for having a separate table header section:

<table>
  <thead>
    <tr>
      <th>Series</th>
      <th>RSquared</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Manual Sizing</td>
      <td>0.98765432</td>
      <td>data...</td>
    </tr>
  </tbody>
</table>

It's more semantically correct, and it also gives you better opportunities to apply styling without requiring extra span elements or classes or what have you.

Depending on your setup, you could even add all the series as rows, and simply hide/show them as needed.

\$\endgroup\$
1
\$\begingroup\$

I don't know how you feel about this but I thought that I would add a reference to it at the least.

You can make a multi-lined input dialog using the textarea tag with the rows attribute, and then you can also specify how many characters you want to allow on each line with the cols attribute.

Edit:

I reread the question and noticed that you want a scrollable textbox that has a dynamic width. all I needed to do was to change the .details td:last-child input to .details td:last-child textarea in the CSS and it works the same, but in Chrome and probably most mobile browsers.

one issue that I noted with your code is that I couldn't scroll through the text in the input from my desktop (Chrome Browser), with the single lined Textarea I am able to make the textarea bigger if I like so that I can see the data. I can also scroll the textarea if I like, but it scrolls vertically instead of horizontally, I couldn't get your version to allow me to scroll at all from my desktop so I wasn't able to see all the number sets.

Anything that you want shown in the textarea has to actually go inside the tags though and not in a value attribute of the tag

.container {
    width: 80%;
    margin: 0 auto;
    border: 2px solid black;
}

#dummy {
    width: 100%;
    background-color: lightgreen;
}

.details {
    width: 100%;
    border-collapse: collapse;
}

.details td {
    border: 1px black solid;
    padding: 3px;
}

.details td:last-child {
    width: 100%;
    background-color: lightblue;
    padding-right: 7px;
}

.details td:last-child textarea {
    width: 100%;
}
    <div id="dummy" >text to show where a graph would be</div>
    <hr>

    Manual visualization

    <table class="details">
      <tr>
        <td>
          <label for="seriesName">Series</label>
          <input id="seriesName" type="text" size="15" readonly="readonly" value="Manual Sizing" >
        </td>
        <td>
          <label for="seriesRSquare">RSquared</label>
          <input id="seriesRSquare" type="text" size="10" readonly="readonly" value="0.98765432" >
        </td>
        <td>
          <label for="seriesDetail">Description</label>
          <textarea id="seriesDetail" type="text" readonly="readonly" 
             rows="1" >[1,23],[2,20],[4,20],[8,21],[16,23],[32,22],[64,26],[128,28],[256,41],[512,55],[1024,81],[2048,136],[4096,244],[8192,474],[16384,959],[32768,1987],[65536,3613],[131072,6957],[262144,14250],[524288,28215],[1048576,55882],[2097152,116210],[3145728,175000],[4194304,229976],[5242880,291501],[6291456,347649],[7340032,399349],[8388608,485512]</textarea>
        </td>
      </tr>
    </table>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.