简体   繁体   中英

How to align legend elements dynamically?

Question

How do I align the ticks and text labels with the colour gradient, and so that the legend container expands to contain those elements

在此处输入图片说明

Notes

  • The colour gradient, ticks and labels have to be created dynamically in JS
  • The width of labels will vary, so the legend container has to expand accordingly
  • I can't use JQuery
  • I'm not a javascript/html/css developer, so happy to hear alternative approaches

HTML

<div id="legend"></div>

Javascript

var legend = document.getElementById("legend");

var divColours = document.createElement('div');   
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';

style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';' 
style += 'background: linear-gradient' + colours + ';'

divColours.setAttribute('style', style);
legend.appendChild(divColours);

for (var i = 0; i < 7; i++) {

  var left = 10 + 10 + 1; 
  var top = 10 + (i * 20);

  var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 3px; height: 1px; background: #b8b9ba;';
  var tickVal = 'position: absolute; top: ' + (top - 5) + 'px; left: ' + (left + 5) + 'px; background: red; color: #b8b9ba;';

  var divTicks = document.createElement('div');
  var divVal = document.createElement('div');

  divTicks.setAttribute('style', tick);
  divVal.setAttribute('style', tickVal);
  divVal.innerHTML = ' this is a variable ' + i;

  legend.appendChild(divTicks);
  legend.appendChild(divVal);
}

CSS

#legend {
    font-family: Arial, sans-serif;
    background: #fff;
    padding: 10px;
    margin: 10px;
    border: 1px solid #b8b8b8; 
    border-radius: 4px;
    height: auto;
    display: inline-block;
}

Working Demo

Related

I'm trying to adapt this answer

I wrapped your ticks on a parent div tag and appended ticks inside it. Replace your current JavaScript code with following one. I think you want something like this.

JavaScript

var legend = document.getElementById("legend");

var divColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';

style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';'
style += 'background: linear-gradient' + colours + ';'

divColours.setAttribute('style', style);
legend.appendChild(divColours);

var divTicksParent = document.createElement('div');
divTicksParent.style.position = "absolute";
divTicksParent.style.width = "200px";
divTicksParent.style.top = "28px";

legend.appendChild(divTicksParent);

for (var i = 0; i < 7; i++) {
  var left = 10;
  var top = (i * 23) + (1);
  var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 6px; height: 1px; background: #b8b9ba;';
  var tickVal = 'position: absolute; top: ' + (top - 6) + 'px; left: ' + (left + 12) + 'px; color: #b8b9ba; font-size: 12px;';

  var divTicks = document.createElement('div');
  var divVal = document.createElement('div');

  divTicks.setAttribute('style', tick);
  divVal.setAttribute('style', tickVal);
  divVal.innerHTML = ' this is a variable ' + i;

  divTicksParent.appendChild(divTicks);
  divTicksParent.appendChild(divVal);
}

CSS

#legend {
  font-family: Arial, sans-serif;
  background: #fff;
  padding: 10px;
  margin: 10px;
  border: 1px solid #b8b8b8;
  border-radius: 4px;
  height: auto;
  width: 130px;
  display: inline-block;
}
<head>
<style>
#legend {
   font-family: Arial, sans-serif;
    background: #fff;
    padding: 10px;
    margin: 10px;
    border: 1px solid #b8b8b8; 
    border-radius: 4px;
    display:inline-flex;

}
</style>

</head>    
<body onload="myFunc()">
      <div id="legend"></div>
    <script>
    function myFunc(){
    var legend = document.getElementById("legend");
    var divColours = document.createElement('div');
    var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
    var colours = '(' + jsColours.join() + ')';

    style = 'height: ' + jsColours.length * 20 + 'px; width: 10px; ';
    style += 'background: ' + jsColours[1] + ';';
    style += 'background: -webkit-linear-gradient' + colours + ';'
    style += 'background: -o-linear-gradient' + colours + ';'
    style += 'background: -moz-linear-gradient' + colours + ';'
    style += 'background: linear-gradient' + colours + ';'

    divColours.setAttribute('style', style);
    legend.appendChild(divColours);

    var divTicksParent = document.createElement('div');
    divTicksParent.style.position = "relative";
    divTicksParent.style.width = "170px";


    legend.appendChild(divTicksParent);

    for (var i = 0; i < 7; i++) {
      var left = 20;
      var top = (i * 23) + (1);
      var tick = 'position: absolute; top: ' + top + 'px; left: ' + left + 'px; width: 8px; height: 1px; background: #b8b9ba;';
      var tickVal = 'position: absolute; top: ' + (top - 8) + 'px; left: ' + (left + 15) + 'px; background: red; color: #b8b9ba;';

      var divTicks = document.createElement('div');
      var divVal = document.createElement('div');

      divTicks.setAttribute('style', tick);
      divVal.setAttribute('style', tickVal);
      divVal.innerHTML = ' this is a variable ' + i;

      divTicksParent.appendChild(divTicks);
      divTicksParent.appendChild(divVal);
    }
    };
    </script>
    </body>

check the demo, I've updated

The other solutions didn't quite answer my question about auto-sizing the width based on the content.

I think this resolves my problem

Javascript

var legend = document.getElementById("legend");

var tickContainer = document.createElement("div");
tickContainer.setAttribute('class', 'labelContainer');

var labelContainer = document.createElement("div");
labelContainer.setAttribute('class', 'labelContainer');

var legendColours = document.createElement('div');
var jsColours = ["#440154", "#443A83", "#31688E", "#21908C", "#35B779", "#8FD744", "#FDE725"];
var colours = '(' + jsColours.join() + ')';

style = 'display: inline-block; height: ' + jsColours.length * 20 + 'px; width: 10px;';
style += 'background: ' + jsColours[1] + ';';
style += 'background: -webkit-linear-gradient' + colours + ';'
style += 'background: -o-linear-gradient' + colours + ';'
style += 'background: -moz-linear-gradient' + colours + ';' 
style += 'background: linear-gradient' + colours + ';'

legendColours.setAttribute('style', style);
legend.appendChild(legendColours);

for (var i = 0; i < jsColours.length; i++) {
  var tickVal = 'text-align: center; color: #b8b9ba; font-size: 12px; height: 20px;';

  var divTicks = document.createElement('div');
  var divVal = document.createElement('div');

  divTicks.setAttribute('style', tickVal);
  divTicks.innerHTML = '-';
  tickContainer.appendChild(divTicks);

  divVal.setAttribute('style', tickVal);
  divVal.innerHTML = ' this is a variable ' + i;
  labelContainer.appendChild(divVal);
}

legend.appendChild(tickContainer);
legend.appendChild(labelContainer);

CSS

.legend {
  font-family: Arial, sans-serif;
  background: #fff;
  padding: 8px;
  margin: 8px;
  border: 1px solid #b8b8b8; 
  border-radius: 4px;
  display:inline-flex;
}

.labelContainer{
  border: 1px solid #00FF00;
  padding-left: 4px;
  height: auto;
  display: inline-block;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM