I want to show tooltips text in the chart according to my condition.
If my text value is 0 then I want to hide text otherwise show the text of the tooltip.
Series.columns.template.tooltipText = `{valueY}s`;
It gives value according to {valueY}. but I want to it doesn't show when {valueY} is equal to 0(zero).
You can use an adapter for the tooltip disabled property:
var series = chart.series.push(new am4charts.ColumnSeries());
// ...
series.tooltipText = "{valueY.value}s";
series.tooltip.adapter.add("disabled", function(disabled, target) {
if (target.dataItem && target.dataItem.values.valueY.value === 0) {
return true;
}
return disabled;
});
Alternatively for target.dataItem.values.valueY.value === 0 you can use target.dataItem.dataContext.yourProperty === 0.
Here is a code pen, which shows the result.
I am working on something similar to the this.
This visualization shows all items in the legend at the time of loading. What I am trying to do is that when the visualization loads there are only few items checked in the legend and also visible on the chart for example: Tyrell Corp, Stark Ind and Rekall. For rest of them, I should have the option to turn on/make visible.
This is only required at the time of loading. After that I want the legend to behave normally as is does in this example.
I think something needs to change in this part of the code:
// Get a unique list of Owner values to use when filtering
var filterValues = dimple.getUniqueValues(data, "Owner");
// Get all the rectangles from our now orphaned legend
myLegend.shapes.selectAll("rect")
// Add a click event to each rectangle
.on("click", function (e) {
// This indicates whether the item is already visible or not
var hide = false;
var newFilters = [];
// If the filters contain the clicked shape hide it
filterValues.forEach(function (f) {
if (f === e.aggField.slice(-1)[0]) {
hide = true;
} else {
newFilters.push(f);
}
});
// Hide the shape or show it
if (hide) {
d3.select(this).style("opacity", 0.2);
} else {
newFilters.push(e.aggField.slice(-1)[0]);
d3.select(this).style("opacity", 0.8);
}
// Update the filters
filterValues = newFilters;
// Filter the data
myChart.data = dimple.filterData(data, "Owner", filterValues);
// Passing a duration parameter makes the chart animate. Without
// it there is no transition
myChart.draw(800);
});
Replace this:
// Get a unique list of Owner values to use when filtering
var filterValues = dimple.getUniqueValues(data, "Owner");
with this:
var filterValues = [];
var shapes = myLegend.shapes[0];
//By default, have only three owners showing up and the rest faded.
for (var i=0; i < shapes.length; i++)
{
if (i < 3)
{
var filterValue = $("text", shapes[i]).text();
filterValues.push(filterValue);
}
else
{
var rect = $("rect", shapes[i]);
rect.css("opacity", 0.2);
}
}
// Filter the data and redraw the chart to show only for three owners.
myChart.data = dimple.filterData(data, "Owner", filterValues);
myChart.draw();
I am extending a texbox control with AJAX Autocomplete and I have successfully implemeted an autocomplete text box where once the user enters 3 characters my database returns a list of records that begin with the first 3 characters entered by the user.
I then changed this feature to use some Fuzzy logic so that the strings that returned contain no less than the 3 characters entered by the user and progressively becomes a shorter more refined list as the user enters a more specific search string.
I then used the inlcluded CSS class of the Autocomplete control to change the backgorund color and selected item color in the extended texbox.
<asp:AutoCompleteExtender
ID="TextBox1_AutoCompleteExtender"
runat="server"
DelimiterCharacters=""
Enabled="True"
EnableCaching="True"
ServiceMethod="GetCompletionList"
ServicePath="~/search/strngSrch.asmx"
TargetControlID="TextBox1"
UseContextKey="True"
CompletionSetCount="30"
CompletionInterval="10"
MinimumPrefixLength="2"
CompletionListItemCssClass="itemHighlighted"
CompletionListHighlightedItemCssClass="itemHighlighted1">
</asp:AutoCompleteExtender>
What I would like to do now is change the color of the text ONLY in each string (list item) that matches what the user is entering after 3 or more characters have been entered.
I have been searching for something like this on the web for 2 days and have not found a similar solution. My efforts have become more than frustrating.
User Enters: fish
Results list should look like:
Fishing (The 4 letters = to Fish should be red in each of these list items)
New Fishing licenses
Renew Fishing License
Fish and hatchery lists
If anyone has any links or similar type of solution I would be very pleased to look it over.
This functionality could best be compared to searching for a text string in a PDF where the word background is highlighted yellow for each occurance within the doc. I don't care if it turns the background a different color ONLY behind the text the user entered, or changes the text color.
thanks,
I would like to thank the link below for providing a solution to the question. I finally found something that almost worked. In the interest of not posting only a link, please review the working code below.
Note some of my minor changes in the below code over the original found in the link at the end.
<script type="text/javascript">
function aceSelected(sender, e) {
var value = e._item.innerText; // get_text();
if (!value) {
if (e._item.parentElement && e._item.parentElement.tagName == "LI")
value = e._item.parentElement.attributes["_innerText"].value;
else if (e._item.parentElement && e._item.parentElement.parentElement.tagName == "LI")
value = e._item.parentElement.parentElement.attributes["_innerText"].value;
else if (e._item.parentNode && e._item.parentNode.tagName == "LI")
value = e._item.parentNode._value;
else if (e._item.parentNode && e._item.parentNode.parentNode.tagName == "LI")
value = e._item.parentNode.parentNode._innerText;
else value = "";
}
var searchText = $get('<%=TextBox1.ClientID %>').value;
searchText = searchText.replace('null', '');
sender.get_element().value = value;
}
function acePopulated(sender, e) {
//Give BehaviourId here
var behavior = $find('AutoCompleteEx');
var target = behavior.get_completionList();
if (behavior._currentPrefix != null) {
var prefix = behavior._currentPrefix.toLowerCase();
var i;
for (i = 0; i < target.childNodes.length; i++) {
var sValue = target.childNodes[i].innerHTML.toLowerCase();
if (sValue.indexOf(prefix) != -1) {
var fstr = target.childNodes[i].innerHTML.substring(0, sValue.indexOf(prefix));
var pstr = target.childNodes[i].innerHTML.substring(fstr.length, fstr.length + prefix.length);
var estr = target.childNodes[i].innerHTML.substring(fstr.length + prefix.length, target.childNodes[i].innerHTML.length);
target.childNodes[i].innerHTML = "<div class='autocomplete-item'>" + fstr + '<B><font color=red>' + pstr + '</font></B>' + estr + "</div>";
}
}
}
}
On your AutoComplete Extender provide the following values....
BehaviorID="AutoCompleteEx"
OnClientPopulated="acePopulated"
OnClientItemSelected="aceSelected"
That is about it, I had to perform some minor changes and debugging. Like the closing java script tag is wrong, and the function to get the value from the textbox did not work with e.get_value() so I changed it to e._item.innerText and seem to be working just fine.
Source of Solution
If for example I have a chart with three series in it and the tooltips are set to shared, I would like more control over formatting the tooltips. Currently I use the formatter: somefunction() and create my own html to use in the tooltip that is displayed. Now this works very nicely, but now I would like to be able to know when the formattor function fires which series I am over so that out of the three series in the tooltip I can format the text I show accordingly.
Shared Tooltip:
Header Label
Series 1
Series 2 (If I am hovering over this item I want to bold it in the formatter function)
Series 3
There isn't such info in shared tooltip - simply you can hover empty space on a chart (none of series) and it will be displayed, see: http://jsfiddle.net/LBsL5/
Solution which may work for you is to disable shared tooltip and get values from other series using:
var xIndex = this.series.xData.indexOf(this.x),
allSeries = this.series.chart.series;
Now loop over all series and use allSeries[index].yData[xIndex] to get value from each series.
Of course, if this.series.index (or this.series.options.index ) is the same index above, then generate bold text.
Thanks for the direction on this. I am posting the full code here to implement this. Hopefully it will help others.
// Header for tooltip.
// This row consists of bold text, with the text being the xAxis Label
// that the Series falls in followed by the Chart Title.
var toolTip = '<b>' + this.x + ' ' + chartTitle + '</b><br/>';
// Get the current index in the Series you are hovering over.
var xIndex = this.series.xData.indexOf(this.point.x);
// Get all the Series represented in the Chart.
var allSeries = this.series.chart.series;
// Loop over each Series.
for (var index = 0; index < allSeries.length; index++) {
// Get the value from each Series.
var yDataValue = allSeries[index].yData[xIndex];
// Check if this is the same as index and if it is then you are
// hovering over the point that needs the text in the formatted tooltip in bold for that Series.
if (this.series.index === index || this.series.options.index === index) {
//
// Generate Bold Text here.
//
toolTip = toolTip + '<b>' + allSeries[index].name + ': ' + yDataValue + '</b>';
}
else {
toolTip = toolTip + allSeries[index].name + ': ' + yDataValue;
}
}
i'm writing a little coffeescript/js app that allows user to design icons ( 16x16 pixels or 32X32 pixels ).
The icon is actually a 2 dimensional array with color cells. A cell can have a color or be empty.
I want the user to be able to fill blank cells with a "bucket paint" tool.
It means that
if the user clicks on a blank cell , all the cells that are blank next to the clicked cell with be filled with the choosen color , until it reaches a colored cell
if the user clicks on a colored cell , all the cells that are next to the clicked cell and share the same color will be filled , but not the blank ones nor the colored ones ( with another color ).
The app already allows the user to fill cells one by one with a chosen color , or delete colored cells with a pen tool.
Any suggestions ?
(ps : i'm not using html canvas to draw )
Since this is only 16x16 or 32x32 you can use a recursive solution:
Say your starting point is to change pixel x/y from color A to color B (A or B can be empty).
In pseudo code:
function floodfill(x,y,A,B) {
if ((x<0) || (x>15) || (y<0) || (y>15)) return;
if (get_color(x,y)!=A) return;
set_color(x,y,B);
floodfill(x-1,y-1,A,B);
floodfill(x-1,y,A,B);
floodfill(x-1,y+1,A,B);
floodfill(x,y-1,A,B);
floodfill(x,y+1,A,B);
floodfill(x+1,y-1,A,B);
floodfill(x+1,y,A,B);
floodfill(x+1,y+1,A,B);
}
I'm not entirely sure what type of suggestions you're looking for, but you should take a look at flood fill algorithms.
Here it is on Wikipedia: http://en.wikipedia.org/wiki/Flood_fill
Allright , here is how i solve my problem in coffeescript.
It is an exemple using canvas.
the script should run on any page where there is a canvas element with a id of canvas , i had to create my own stack because of stackoverflow issues.
log = ->
console.log arguments
class Point
constructor:(#x,#y)->
class BucketFiller
MAXITERATION:100000
factor:1
fill : (ctx,pixel, colCible, colRep)->
P = []
max = #MAXITERATION
if #getColorAtPixel(ctx,pixel)!=colCible then return null
P.push(pixel)
while P.length > 0 and max >=0
--max
currentpixel = P.pop()
#fillRect(ctx,currentpixel.x,currentpixel.y,#factor,#factor,colRep)
if #isInCanvas(ctx,currentpixel)
if #getColorAtPixel(ctx,#up(currentpixel)) == colCible then P.push(#up(currentpixel))
if #getColorAtPixel(ctx,#down(currentpixel)) == colCible then P.push(#down(currentpixel))
if #getColorAtPixel(ctx,#right(currentpixel)) == colCible then P.push(#right(currentpixel))
if #getColorAtPixel(ctx,#left(currentpixel)) == colCible then P.push(#left(currentpixel))
return
fillRect:(ctx,x,y,width,height,color)->
ctx.fillStyle = color
ctx.fillRect(x,y,width,height)
return
down :(pixel)->
return {x:pixel.x,y:pixel.y-#factor}
up:(pixel)->
return {x:pixel.x,y:pixel.y+#factor}
right :(pixel)->
return {x:pixel.x+#factor,y:pixel.y}
left :(pixel)->
return {x:pixel.x-#factor,y:pixel.y}
getColorAtPixel:(ctx,pixel)->
try
imageData = ctx.getImageData(pixel.x,pixel.y,1,1)
catch e
return null
return #rgbArrayToCssColorString(imageData.data)
rgbArrayToCssColorString:(array)->
result = "rgb(#{array[0]},#{array[1]},#{array[2]})"
return result
isInCanvas : (ctx,pixel)->
result = ((0 <= pixel.x <= ctx.canvas.width) and (0 <= pixel.y <= ctx.canvas.height))
return result
main=->
buckfiller = new BucketFiller()
log("start")
canvas = document.getElementById("canvas")
ctx = canvas.getContext("2d")
penPosition = new Point(2,10)
fillColor = "rgb(255,0,0)"
colCible = buckfiller.getColorAtPixel(ctx,penPosition)
try
buckfiller.fill(ctx,penPosition,colCible,fillColor)
catch e
log e
window.onload=->
main()