I'm working on a leaflet js map atm.
There are some items that I want to apply a class to, depending on their inner text. Seems as though two circles at a certain size just overlap. Adding some CSS in that case so they're no longer overlapping.
//function searches for all <text> elements within svg tags for the queryText
// and then appends them with the appendText
function addClasserino() {
let elements = document.querySelectorAll('map-marker marker-bg-condition'); // get all circle elements as a NodeList
elements.forEach(el => { // go through each text element
if (el.innerText < 10) { // if the innerHTML matches the query HTML then
elements.addClass('updated'); // add the class
}
})
}
document.addEventListener("DOMContentLoaded", function(){
//pass in the search text and the appending text as arguments
addClasserino();
});
This is what I got so far. Doesn't seem to be working.
.map-marker.marker-bg-condition needs to be moved across a bit. Got the CSS here:
.map-marker.marker-bg-condition.updated{
margin-top: -19px;
margin-left: -19px;
}
With Leaflet JS, the zoom level changes and items are updated accordingly. This of my map showing all details at the world view, and then breaking down to state as you zoom in.
The unexpected behavior is that the css isn't applying and where bubbles are overlapping is because of this. This is the original code but I can't change it and get it to work even with an if statement.
getMarkerHtml: function(count, color) {
var size = this.getMarkerSize(count);
var hsize = (size / 2) - 6;
var font = count < 1000 ? Math.ceil(size / 3) : Math.ceil(size / 4);
if(count < 100) {
font = font + 3;
}
var cluster_classes = [
'map-marker',
'marker-bg-' + (Filters.colors.profile === color ? 'profile' : 'condition')
];
if(this.zoomLevel !== 'zip') {
size = size * 1.5;
if(petMapFilters.colors.profile !== color) {
hsize = size / 2;
}
}
if(this.zoomLevel === 'zip') {
var cluster_styles = [
'margin-left: -' + hsize + 80 + 'px;', NOTE: I tried this to offset on zip zoom bit it's not working END OF NOTE
'margin-top: -' + hsize + 80 +'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];
} else {
var cluster_styles = [
'margin-left: -' + hsize + 'px;',
'margin-top: -' + hsize + 'px;',
'width: ' + size + 'px;',
'height: ' + size + 'px;',
'font-size: ' + font + 'px;'
];};
var div_style = [
'line-height: ' + (size - (size * 0.3)) + 'px;'
];
count = this.formatCount(count);
return '<div class="' + cluster_classes.join(' ') + '" tabindex="0" style="' + cluster_styles.join(' ') + '"><div style="' + div_style.join(' ') + '">' + count + '</div></div>';
},
Please let me know what I am doing wrong here as I am not able to identify this myself.
The issue at hand:
Thanks.
Related
I'm working on a project I inherited involving JS which I'm new to. I need to change the z-index of markers on a map and a few other objects on the page.
Is there a way to set the z-index for all my features (to 7) when they are imported? I tried z-index: 7; in .setHTML. Any other suggestions?
geojson.features.forEach(function(feature) {
let type = feature.properties['type'];
let symbol = icons[type];
// create class names to use as tags for filtering
let typeTag = typeTags[type];
let title = feature.properties['title'];
let impact = feature.properties['impact'];
let impactTag = impactTags[impact];
let sType = feature.properties['studyType'];
let studyType = studyTypes[sType];
let tooltipStudy = feature.properties['studyType'];
let ttStudy = tooltipStudyTypes[tooltipStudy];
let uniqueStudies = feature.properties['unique'];
let uniqueStudy = unique[uniqueStudies]
// replave hash marks with smart quotes
let summary = feature.properties['summary'];
summary = "\u201c" + summary + "\u201d";
let url = feature.properties['link'];
let citation1 = feature.properties['citation'];
let clipCitation = citation1.split("),")[0];
console.log(clipCitation)
let substr = "pdf";
if (url.indexOf(substr) !== -1) {
clipCitation = clipCitation + " [pdf]";
}
// create a HTML element for each feature
var el = document.createElement('div');
el.className = "marker" + " " + typeTag + " " + impactTag;
el.innerHTML = '<i class="' + symbol + '"></i>';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 10, closeButton: false }) // add popups
.setHTML('<h4 style="padding-bottom: 4px; border-bottom: 2px solid ' + colors[impactTag] + ';">' + feature.properties['title'] + '</h4><ul class="list-group list-tooltip"><li>Area of study: ' + feature.properties['location'] + '</li><li><div style="display:inline-block" class=' + impactTag + '>' + popupIcon[type] + "</div>"
+ impactTag + " " + 'that climate change increases the risk of wildfires.</li></ul><p class="summary">'
+ summary + '</p><p class="citation"><a href="'
+ url + '" target="_blank">' + clipCitation + "),</a><span class='citation2'> " + feature.properties['journal'] + '</span></p>'))
.addTo(map);
});
To change any CSS styles with JavaScript use document.getElementById("item").style.XXX = "value";, change XXX with the thing you want to change, in your case z-index:
document.getElementById("item").style.zIndex = "7";
you can do the same thing with jQuery with more simple way :
$("#item").css("z-index","7");
I have a Pie chart with multiple rings and created a Custom Tooltips function with below code:
function tooltipWithTotalP(tooltipItem, data) {
var label = data.labels[tooltipItem.index];
var values = data.datasets[tooltipItem.datasetIndex].data;
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
var total = 0;
for (var i in values) {
total += values[i];
}
var percentage = Math.round((value / total) * 100);
var totally = total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if (tooltipItem.datasetIndex !== data.datasets.length - 1) {
return label + " : " + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' (' + percentage + '%)';
} else {
return [label + " : " + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' (' + percentage + '%)', "Total : " + totally];
}
}
The above function is expected to show all the Label values with Total at bottom from the PieChart, but it is showing only individual Values from First Dataset and individual values + Total from second Dataset.
Individual lebels are showing as Undefined.
Here is the JSfille https://jsfiddle.net/kingBethal/x03w2qbk/40/
To see every label remove the tooltipItem.index
var label = data.datasets[tooltipItem.datasetIndex].labels;
To list all the labels in the tool tip is straight forward.
var label = [];
for (var j in labels) {
var percentage = Math.round((values[j] / total) * 100);
label.push (labels[j] + " : " + values[j].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' (' + percentage + '%)');
}
label.push("Total : " + totally)
return label;
Label color is derived from the datasetIndex so the label background colour doesn't propagate, you will have to create a custom tooltip or disable displayColors.
custom: function(tooltip) {
tooltip.displayColors = false;
},
https://jsfiddle.net/drillep/xb4g19en/2/
The label variable in the label function needs an array index.
var label = data.datasets[tooltipItem.datasetIndex].labels[tooltipItem.index];
https://jsfiddle.net/drillep/40htzrdn/
EDIT - I don't think I explained it very well the first time.
I have a lot of data - it's in an Array, with each item in the array being an object. In the system I am working in (a control system for A/V devices, which uses JavaScript as the programming language), I am generating buttons based on the length of the array. I want to be able to position a button, and essentially know the X and Y coordinates for each button in the array - with X and Y being Row/Column. (which I then translate to a X/Y pixel position on my UI.
My initial code, which is below, is within a for loop, and I manually calculated the button position. But this is tedious, as I use this same function to show off different groups/sizes of buttons.
Anywhere there is mirage.log = console.log.
The code below is part of a For Loop
button.element.style.position = 'absolute'; //Do to all Buttons.
if (i == 0) //First Item
{
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = btn_Info.startTop + 'px';
}
else if (i <= btn_Info.numRow-1) //First Column.
{
mirage.log('Setting Position of First Column');
button.element.style.left = btn_Info.startLeft + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * i + btn_Info.startTop + 'px';
}
else if (i > btn_Info.numRow - 1 && i <= btn_Info.numRow * 2 - 1)
{
mirage.log('Setting Second column ' + i);
button.element.style.left = btn_Info.startLeft + btn_Info.width + btn_Info.hOffset + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i-btn_Info.numRow) + btn_Info.startTop + 'px';
}
else
{
mirage.log('Setting Third column ' + i);
button.element.style.left = btn_Info.startLeft + ((btn_Info.width + btn_Info.hOffset)*2) + 'px'; button.element.style.top = (btn_Info.height + btn_Info.vOffset) * (i - (btn_Info.numRow*2)) + btn_Info.startTop + 'px';
}
Thanks in advance for the help - I have grabbed so many answers from this forum over the last year, you guys are awesome!
EDIT -
I was able to get some adjustment if I generate rows first then columns:
I was able to get a little close with the help of a friend, and be able to adjust for a 2 column layout by doing the following:
encoder = {
'buttonVals':{'width':125,'height':50,'numCols':2,'numRows':null;'vOffset':10,'hOffset':10}
var posLeft;
var posTop;
posLeft = (i % encoder.buttonVals.numCols) * (encoder.buttonVals.width + encoder.buttonVals.hOffset) + encoder.buttonVals.startLeft;
posTop = Math.floor(i / encoder.buttonVals.numCols) * (encoder.buttonVals.height + encoder.buttonVals.vOffset) + encoder.buttonVals.startTop;
After working on this for a bit - here is the code that I got to work. This prints out both the row position, and the column position.
testFunction = function(incRow, incCol){
var myFunc = {
'testLength':0,
'numRows':incRow,
'numCols':incCol,
'array':[],
};
myFunc.testLength = incRow * incCol;
for(var c=0, posCol = 0, posRow = 0; c < myFunc.testLength; c++)
{
var whichRow;
posRow = Math.floor(c/myFunc.numRows);
whichRow = Math.floor(c/myFunc.numRows) + c;
if (whichRow > myFunc.numRows)
{
whichRow = whichRow - (myFunc.numRows * posRow) - posRow;
if (whichRow === 0)
{
posCol = posCol + 1;
}
}
console.log(c + ' : ' + whichRow + ' : ' + posCol);
}
};
testFunction(6,4);
I am working with some CSS Backgrounds (http://css3pie.com/demos/gradient-patterns/) in an application and want to be able to scale the design with a slider. Here's a JSFiddle. I was able to scale X & Y separately on some like the Stripes and Picnic designs where I just had to play with background-size:50px 50px; like this:
//setup the variables based off the css which was set using dropdown
gridItems = $(document.activeElement).val().split("; ");
for (i = 0; i < gridItems.length -1; i++) {
gridSettings = gridItems[i].split(":");
if (gridSettings[0]=="background-size"){
gridSize = gridSettings[1].split(" ");
gridX = gridSize[0];
gridY = gridSize[1]
}
//on the action of the slide - update value
$('#gridXY-'+key).on("slide", function(slideEvt) {
gridXY = slideEvt.value;
$('.draggable-' + currentLayer).css("background-size", "calc("+ gridX +" * "+ gridXY +") calc("+ gridY +" * "+ gridXY +")");
});
Which can be set either numerically or using but when it gets to something like the Blue Print it has a lot more settings background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px;
I am trying to do this right so that it can take a variable number of those, and can write something that could work, but the method I have in mind is really messy, hoping for some help scaling this that might be a little cleaner than what I would do.
I did find this:http://codepen.io/Erik/pen/JGnsB but he is using LESS to declare variables, if possible I would like to stay away from that.
UPDATE:
Here is a JSFiddle of it: http://jsfiddle.net/4L3d9qh2/
I added a function that should have let me update it, but for some reason the calc() function doesn't seem to be working to update the div style. After processing, it looks like this:
$('.draggable-0').css("background-size", calc(100px - 4) calc(100px - 4), calc(100px - 4) calc(100px - 4), calc(20px - 4) calc(20px - 4), calc(20px - 4) calc(20px - 4));
$.each(gridSizeArray, function( k, v ){
if (gridIncrement==1)
{
gridXY = "calc(" + v +" - " + value + ") ";
}else{
if(isOdd(gridIncrement)){
gridXY = gridXY + "calc(" + v +" - " + value + ") ";
}else{
gridXY = gridXY + "calc(" + v +" - " + value + "), ";
}
}
gridIncrement++
})
Here was the final code that works. Using .each() loop through and if it is even, add a comma, then remove the last comma at the end.
gridItems = $(document.activeElement).val().split("; ");
for (i = 0; i < gridItems.length -1; i++) {
gridSettings = gridItems[i].split(":");
if (gridSettings[0]=="background-size"){
gridSizeString = gridSettings[1].replace(/,/gi, '');
gridSizeArray = gridSizeString.split(" ");
}
$('[data-type="sliderLayer"][data-layer="'+currentLayer+'"][data-slide="'+currentSlide+'"]').css(gridSettings[0], gridSettings[1]);
}
$.each(gridSizeArray, function( k, v ){
if (gridIncrement==1)
{
gridXY = "calc(" + v +" + " + value + "px) ";
}else{
if(isOdd(gridIncrement)){
gridXY = gridXY + " calc(" + v +" + " + value + "px) ";
}else{
gridXY = gridXY + "calc(" + v +" + " + value + "px),";
}
}
gridIncrement++
})
if (isOdd(gridIncrement))
{
gridXY = gridXY.substring(0, gridXY.length - 1);
}
I have the following JS code that changes the width depending on value of the data-percentage HTML attribute:
var addRule = (function (sheet) {
if(!sheet) return;
return function (selector, styles) {
if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
if (sheet.addRule) return sheet.addRule(selector, styles);
}
}(document.styleSheets[document.styleSheets.length - 1]));
var i = 101;
while (i--) {
addRule("[data-percentage='" + i + "%']", "width:" + i + "%");
}
See the demo: http://jsfiddle.net/YYF35/
Instead of width, for some elements I want to change their height.
How can I change the code so that depending on class of the div I change the height or width of element (depending on the data-percentage attribute number of course)?
I don’t want to create a different HTML attribute for it, like so:
while (i--) {
addRule("[data-percentage-width='" + i + "%']", "width:" + i + "%");
addRule("[data-percentage-height='" + i + "%']", "height:" + i + "%");
}
jQuery can be used as well. Any ideas?
Your code is adding rules. If you really want to be doing that, just add more rules:
var i = 101;
while (i--) {
addRule("[data-percentage='" + i + "%'].change-width", "width:" + i + "%");
addRule("[data-percentage='" + i + "%'].change-height", "height:" + i + "%");
}
Now, elements with the change-width class will have their width modified, and elements with the change-height class will have their height modified (and you can use both if you like).
Try this:
$("div[data-percentage]").each(function(){
$(this).css({
width: $(this).attr('data-percentage')
//height: $(this).attr('data-percentage')
});
});
http://jsfiddle.net/YYF35/1/