add Text inside the Boxgroup in heat map dc.js - javascript

is there a way to put a text inside the box group of a heat map in dc.js ?
so that the information is readable without making a hover on the box ?
var ndx2 = crossfilter(budgetsArr);
var budgetDimension = ndx2.dimension(function(d) {return [+d.account, +d.year]; });
var budgetGroup = budgetDimension.group().reduceSum(function(d) { return +d.budget; });
chart
.width(45 * 20 + 80)
.height(45 * 5 + 40)
.dimension(budgetDimension)
.group(budgetGroup)
.keyAccessor(function(d) { return +d.key[0]; })
.valueAccessor(function(d) { return +d.key[1]; })
.colorAccessor(function(d) { return +d.value; })
.title(function(d) {
return "Account: " + d.key[0] + "\n" +
"Year : " + d.key[1] + "\n" +
"Budget: " + (d.value) + " $";})
.colors(["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"])
.calculateColorDomain();
and the result :
I need that the Budget will be readable from the box and not in the title property.
Thank you!

Instead of appending the title add the text element try the following code. If it doesn't work put a plnkr link. I can probably help you to figure out the issue. Look at this link to understand more about adding the text element.
chart
.width(45 * 20 + 80)
.height(45 * 5 + 40)
.dimension(budgetDimension)
.group(budgetGroup)
.keyAccessor(function(d) { return +d.key[0]; })
.valueAccessor(function(d) { return +d.key[1]; })
.colorAccessor(function(d) { return +d.value; })
.append("text")
.attr("x", function(d) { return x(d.value) - 3; })
.attr("y", d.value/ 2)
.attr("dy", ".35em")
.text(function(d) { return "Account: " + d.key[0] + "\n" +
"Year : " + d.key[1] + "\n" +
"Budget: " + (d.value) + " $";}); });

Related

Add a Class to some items depending on inner html

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.

I am looking for a JavaScript random color generator to output the color red 10% of the time

This is what I have so far, I have the background set to a solid color and a div that when clicked generates the random color. I want it to be generated by the space bar, and I want it to output red 10% of the time. I am an amateur at JavaScript but am learning.
var r, g, b, cstring;
function colapply() {
color();
r = newcolor.slice(1, 3);
g = newcolor.slice(3, 5);
b = newcolor.slice(5, 7);
r = parseInt(r, 16);
g = parseInt(g, 16);
b = parseInt(b, 16);
cstring = "rgb(" + r + "," + g + "," + b + ")";
$(".colorc").html("<" + "div class=" + "'" + "colorc1" + "'" + ">" + "<" + "/" + "div" + ">" + newcolor + "<span class='rgb'>" + cstring + "</span>");
$("body").css({
"background": newcolor
});
$(".colorc").css({
"color": newcolor
});
$(".colorc1").css({
"background": cstring
});
}
var newcolor;
function color() {
newcolor = '#' + (Math.random().toFixed(6).toString(16)).slice(2);;
if (newcolor.length < 7) {
color();
}
}
$(".colorc").click(colapply);
colapply();
Try introducing a special case for red.
function color() {
if (Math.random() < 0.1) { // 10% of the time
newcolor = '#FF0000'
return;
}
newcolor = '#' + (Math.random().toFixed(6).toString(16)).slice(2);;
if (newcolor.length < 7) {
color();
}
}

ChartJS: Show all tooltips with Total for Multi Pie chart

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/

HTML5 Drag-Drop: SetDragImage not working

I'm new to front-end programming and experimenting with HTML5 drag-drop. The object to drag is a bootstrap div.panel which does its job pretty well. However, whilst the object is being dragged, I want to show a custom image using SetDragImage function. I've used this function precisely as described in the Mozilla Developer Network, but still its not working - the default blank rectangle is shown when the object is dragged.
Below is the JavaScript for the drag/drop events, and here is the JSFiddle.
<script type="text/javascript">
function drag(ev){
//var style = window.getComputedStyle(ev.target, null);
var ss = (parseInt($(ev.target).position().left,10) - ev.clientX) + ',' + (parseInt($(ev.target).position().top,10) - ev.clientY);
ev.dataTransfer.setData("text/plain", ss);
ev.dataTransfer.setDragImage(document.getElementById("draggit"), 0, 0);
console.log("drag:target", $(ev.target).position().left + "," + $(ev.target).position().top);
console.log("drag:offset", ss);
}
function drop(ev) {
//console.log("drop:" + $(ev.target).position().left + "," + $(ev.target).position().top);
//console.log("drop:" + ev.clientX + "," + ev.clientY);
var offset = ev.dataTransfer.getData("text/plain");
var npos = offset.split(",");
console.log("drop_clientpos:" + ev.clientX + "," + ev.clientY);
console.log("drop_newpos:" + (ev.clientX + parseInt(npos[0])) + "," + (ev.clientY + parseInt(npos[1])));
document.getElementById("dragme").style.left = (ev.clientX + parseInt(npos[0])) + "px";
document.getElementById("dragme").style.top = (ev.clientY + parseInt(npos[1])) + "px";
ev.preventDefault();
return false;
}
function dragOver(ev) {
ev.preventDefault();
return false;
}
</script>

Change value on legend in dc.js

I built a pie chart with dc.js, with the following:
var chart = dc.pieChart(selector, this.chartGroup)
.width(200).height(200)
.dimension(this.dimension)
.group(this.group)
...
.legend(dc.legend().x(10).y(255).gap(5).horizontal(true))
chart.render()
Is there a way to format the labels on the legend with something like the following:
function (d) {
return d.key + ': ' + d.value;
}
The last answer seems partially true. I would suggest the following:
.legend(dc.legend().x(100).y(400).itemHeight(13).gap(5).autoItemWidth(true).legendText(function (d) {
return d.name + " " + Math.round((d.data / totalPrice) * 100) + "%"
}));
Where d.name is the actual label you will see in the legend.
d.data is the actual value.
I also needed to add (%) to the pieChart legend for several graphs. I ended up modifying a copy of the legend.js from dc.js-2.0.0-beta.5\src and include that in my pages.
See http://jsfiddle.net/za8ksj45/36/ for working example
The first ~260 lines is the modified legend.js that can be put in a separate file.
(I don't have a place I could serve it from so I had to include the file content).
The main modification starts at line ~88
itemEnter.append('text')
.text(function(d) {
var legendText = d.name;
if (_showPercent) {
var groupTotal = d.chart.group().all().reduce(function(a, v){ return a + v.value; }, 0);
//legendText = legendText + " (" + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%)";
//legendText = legendText + " = " + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%";
legendText = legendText + " - " + (100*d.data/groupTotal).toFixed(_percentDecimals) + "%";
}
return legendText;
})
.attr('x', _itemHeight + LABEL_GAP)
.attr('y', function () {
return _itemHeight / 2 + (this.clientHeight ? this.clientHeight : 13) / 2 - 2;
});
The modification consists of two new methods for legend()
.displayPercent (default=false to keep original behavior the same)
.percentDecimals (default=1)
The hardest part to figure out was the following line:
var groupTotal = d.chart.group().all().reduce(function(a, v){ return a + v.value; }, 0);
It calculates the grand total for the current filtered group that is driving the pieChart which can be used to calculate the percentage.
I played with a couple different string to show percentage. It should probably be replaced with a string like this: - (%%) where %% gets replaced with the actual percentage. That way you can customize it for each legend without having to touch the code.
Works great for a bunch of pieCharts I used so far. I wanted to share this on stackoverflow since I have gotten so much help from this site myself. If this is useful, I can expand it a bit and submit it for inclusion in some future release.
Now you can simply use the .legendText() method in the dc.legend() object!
In your particular case, the solution would be:
var chart = dc.pieChart(selector, this.chartGroup)
.width(200).height(200)
.dimension(this.dimension)
.group(this.group)
...
.legend(dc.legend().x(10).y(255).gap(5).horizontal(true).legendText(function(d) {
return d.key + ': ' + d.value;
}))
chart.render();
This method is defined here.

Categories

Resources