Related
I'm new to d3.js implementation. Need some help d3.js heatmap
I have a Requirement :
A heat map which shows the difference between each record. based on records Severity and Probability types:
Desired Image :
Data:
In the Above output picture , You can see the circles :
Assume those as records being displayed on a graph .
Code for that starts after Comment " //Add dots or circles " .
Record data example :
{
"group":"Likely",
"variable":"Significant",
"value":79,
"record":"Retention of environmental safety records",
"color":"red"
}
Data for those records are in variable "dots" You can find in the code below. In that I have 3 records . But 2 circles are overlapping .
I have worked on a Heatmap Design .
Combining :
Heatmap : https://www.d3-graph-gallery.com/graph/heatmap_style.html
Connected scatter plot : https://www.d3-graph-gallery.com/graph/connectedscatter_tooltip.html
For now , I have just updated the data :
I have 2 Issues :
Overlapping dots issue
Tooltip not showing after Updating to svg
Detail:
1. Overlapping dots issue
Data for those records are in variable "dots" You can find in the code below. In that I have 3 records . But 2 circles are overlapping .
The desired Output is something like this : Circles should not be Overlapped .
If two records with same data , It should display 2 records. I need help in implenting that . Any suggestion is appreciated .
** 2. ToolTip Issue :**
I had an Issue with Tooltip (It was working with div tag ) previously it was as shown below :
Due to Some requirement i had to go with svg tag in the Html rather than Div tag . since This has to be implemented in Lwc in Salesforce.
Html Updated from div to Svg as shown below :
After Updating ,
Entire Heatmap is working except the Tooltip part .
Updated the Tooltip part to Svg as shown below :
Now the Tooltip is not working .
code :
<!-- Code from d3-graph-gallery.com -->
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v5.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz">
<svg
class="d3"
width={svgWidth}
height={svgHeight}
lwc:dom="manual"
></svg></div>
<!-- Load color palettes -->
<script>
// set the dimensions and margins of the graph
var margin = {top: 80, right: 25, bottom: 30, left: 100},
width = 550 - margin.left - margin.right,
height = 450 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select(this.template.querySelector('svg.d3'))
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
//Read the data
var data = [{"group":"Rare","variable":"Insignificant","value":45,"color":"purple"},{"group":"Rare","variable":"Minimal","value":95,"color":"purple"},{"group":"Rare","variable":"Moderate","value":22,"color":"green"},{"group":"Rare","variable":"Significant","value":14,"color":"green"},{"group":"Rare","variable":"Catastrophic","value":59,"color":"yellow"},{"group":"Unlikely","variable":"Minimal","value":37,"color":"purple"},{"group":"Unlikely","variable":"Insignificant","value":37,"color":"purple"},{"group":"Unlikely","variable":"Moderate","value":81,"color":"green"},{"group":"Unlikely","variable":"Significant","value":79,"color":"yellow"},{"group":"Unlikely","variable":"Catastrophic","value":84,"color":"orange"},{"group":"Probable","variable":"Insignificant","value":96,"color":"purple"},{"group":"Probable","variable":"Minimal","value":37,"color":"green"},{"group":"Probable","variable":"Moderate","value":98,"color":"yellow"},{"group":"Probable","variable":"Significant","value":10,"color":"orange"},{"group":"Probable","variable":"Catastrophic","value":86,"color":"red"},{"group":"Likely","variable":"Insignificant","value":75,"color":"green"},{"group":"Likely","variable":"Minimal","value":18,"color":"yellow"},{"group":"Likely","variable":"Moderate","value":92,"color":"orange"},{"group":"Likely","variable":"Significant","value":43,"color":"red"},{"group":"Likely","variable":"Catastrophic","value":16,"color":"red"},{"group":"Almost Certain","variable":"Insignificant","value":44,"color":"green"},{"group":"Almost Certain","variable":"Minimal","value":29,"color":"yellow"},{"group":"Almost Certain","variable":"Moderate","value":58,"color":"orange"},{"group":"Almost Certain","variable":"Significant","value":55,"color":"red"},{"group":"Almost Certain","variable":"Catastrophic","value":65,"color":"red"}]; // Labels of row and columns -> unique identifier of the column called 'group' and 'variable'
var myGroups = d3.map(data, function(d){return d.group;}).keys()
var myVars = d3.map(data, function(d){return d.variable;}).keys()
// Build X scales and axis:
var x = d3.scaleBand()
.range([ 0, width ])
.domain(myGroups)
.padding(0.05);
svg.append("g")
.style("font-size", 15)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(0))
.select(".domain").remove()
// Build Y scales and axis:
var y = d3.scaleBand()
.range([ height, 0 ])
.domain(myVars)
.padding(0.05);
svg.append("g")
.style("font-size", 15)
.call(d3.axisLeft(y).tickSize(0))
.select(".domain").remove()
// Build color scale
var myColor = d3.scaleSequential()
.interpolator(d3.interpolateInferno)
.domain([1,100])
// create a tooltip
var tooltip = d3.select("#my_dataviz")
.append("div")
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px")
.style("position","fixed")
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover = function(d) {
tooltip
.style("opacity", 1)
d3.select(this)
.style("stroke", "black")
.style("opacity", 1)
}
var mousemove = function(d) {
tooltip
.html("The exact value of<br>this cell is: " + d.value)
.style("left", (d3.mouse(this)[0]+70) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mouseleave = function(d) {
tooltip
.style("opacity", 0)
d3.select(this)
.style("stroke", "none")
.style("opacity", 0.8)
}
// add the squares
svg.selectAll()
.data(data, function(d) {return d.group+':'+d.variable;})
.enter()
.append("rect")
.attr("x", function(d) { return x(d.group) })
.attr("y", function(d) { return y(d.variable) })
.attr("rx", 4)
.attr("ry", 4)
.attr("width", x.bandwidth() )
.attr("height", y.bandwidth() )
.style("fill", function(d) { return d.color } )
.style("stroke-width", 4)
.style("stroke", "none")
.style("opacity", 0.8)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover1 = function(d) {
tooltip
.style("opacity", 1)
d3.select(this)
.style("stroke", "black")
.style("opacity", 1)
}
var mousemove1 = function(d) {
tooltip
.html("4. " + d.record)
.style("left", (d3.mouse(this)[0]+90) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mouseleave1 = function(d) {
tooltip
.style("opacity", 0)
d3.select(this)
.style("stroke", "none")
.style("opacity", 0.8)
}
//Add dots or circles
var dots =
[{"group":"Likely","variable":"Significant","value":79,"record":"Retention of environmental safety records","color":"red"},
{"group":"Unlikely","variable":"Minimal","value":84,"record":"Risk of Fines from European Union GDPR due to data breach","color":"orange"},
{"group":"Unlikely","variable":"Minimal","value":84,"record":"Risk Management Case record","color":"green"}];
// Add the points
svg
.append("g")
.selectAll("dot")
.data(dots)
.enter()
.append("circle")
.attr("class", "myCircle")
.attr("cx", function(d) { return x(d.group) + x.bandwidth()/2 } )
.attr("cy", function(d) { return y(d.variable)+ y.bandwidth()/2 } )
.attr("r", 8)
.attr("stroke", "#69b3a2")
.attr("stroke-width", 3)
.attr("fill", function(d) { return d.color })
.on("mouseover", mouseover1)
.on("mousemove", mousemove1)
.on("mouseleave", mouseleave1)
//})
// Add title to graph
svg.append("text")
.attr("x", 0)
.attr("y", -50)
.attr("text-anchor", "left")
.style("font-size", "22px")
.text("A heatmap");
// Add subtitle to graph
svg.append("text")
.attr("x", 0)
.attr("y", -20)
.attr("text-anchor", "left")
.style("font-size", "14px")
.style("fill", "grey")
.style("max-width", 400)
.text("A short description of the take-away message of this chart.");
</script>
Output (Updated) :
Can someone help me in resolving these issues.
I need to display the multiple dots inside the same squares, each dot as a seperate element . when you hover over it It should display the record it represents.
Any suggestion is appreciated . Thankyou
Give your tooltip a position of fixed:
.style("position","fixed")
This will allow the top and left attributes to impact its positioning.
To make the dots appear within the boxes, change your cx attribute to:
.attr("cx", function(d) { return x(d.group) + x.bandwidth()/2 } )
That should center the dots within each box.
To give the dots their own positioning, the dots need to have their own y and x scales. Just make sure it has the same width and height.
Do you have another dataset for this? If not, I wonder if a different scale would give you the outcome you are looking for.
I'm trying to update the bar chart in d3 based on the input selected by the user. The updated data is being displayed but it is being displayed on the old SVG elements. I tried using exit().remove() but it did not work.
Can anyone edit the code attached below so that the old SVG elements are removed.
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<style>
.rect {
fill: steelblue;
}
.text {
fill: white;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
</head>
<body>
<select id = "variable">
<option >select</option>
<option value="AZ">Arizona</option>
<option value="IL">Illinois</option>
<option value="NV">NV</option>
</select>
<script>
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 500 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var y = d3.scaleLinear()
.domain([0,5])
.range([height, 0]);
var yAxis = d3.axisLeft(y)
.ticks(10);
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var bar;
function update(state)
{
d3.csv("test3.csv", function(error, data)
{
data = data.filter(function(d, i)
{
if (d['b_state'] == state)
{
return d;
}
});
data = data.filter(function(d, i)
{
if (i<10)
{
return d;
}
});
var barWidth = width / data.length;
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Stars");
bar = svg.selectAll("bar")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
bar.append("rect")
.attr("y", function(d) { return y(d.b_stars); })
.attr("height", function(d) { return height - y(d.b_stars); })
.attr("width", barWidth - 1)
.attr("fill", "steelblue");
bar.append("text")
.attr("x", function(d) { return height - y(d.b_stars); })
.attr("y", -40)
.attr("dy", ".75em")
.text(function(d) { return d.b_name; })
.attr("transform", "rotate(90)" );
});
svg.exit().remove();
bar.exit().remove();
}
d3.select("#variable")// selects the variable
.on("change", function() {// function that is called on changing
var variableName = document.getElementById("variable").value;// reads the variable value selected into another variable
update(variableName);});
</script>
</body>
Your problem here is about your bar selection. You can have a look to this part of the d3 documentation: Joining data.
By writing
bar = svg.selectAll("bar")
.data(data)
.enter()
You are selecting all bar elements, joining them data, and with this enter(), you are getting all the data items not linked to a bar element (enter() documentation).
But, your bar selector matches nothing. The parameter of the select()/selectAll() has to be a selector (element, class with ., id with #...). That is why the enter() your enter() selection is creating always new elements above the old ones instead of updating them.
So the first step is to rewrite this selection and creating the DOM elements that will match later this selection:
bar = svg.selectAll(".bar")
.data(data)
.enter()
.append("g")
.attr('class', 'bar')
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
Here, we are selecting all elements with the bar class. If there is no DOM element linked to an item from data, so we are creating it (in the enter() selection), as a new g with the bar class.
With the selection written like this, on the next call of your update, the selectAll('.bar') will match all the g previously created and not apply the enter() selection for existing elements.
To update or remove your existing bars, you can write your code like this:
var barData = svg.selectAll(".bar")
.data(data)
// Bars creation
var barEnter = barData.enter()
.append("g")
.attr('class', 'bar')
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
barEnter.append("rect")
.attr("y", function(d) { return y(d.b_stars); })
.attr("height", function(d) { return height - y(d.b_stars); })
.attr("width", barWidth - 1)
.attr("fill", "steelblue");
barEnter.append("text")
.attr("x", function(d) { return height - y(d.b_stars); })
.attr("y", -40)
.attr("dy", ".75em")
.text(function(d) { return d.b_name; })
.attr("transform", "rotate(90)" );
// Update the bar if the item in data is modified and already linked to a .bar element
barData.select('rect')
.attr("height", function(d) { return height - y(d.b_stars); })
// Remove the DOM elements linked to data items which are not anymore in the data array
barData.exit().remove()
I am attempting to add a simply bar chart to my tooltip; it consists of 2 variables -- men and women. I was hoping someone might be able to help me put this inside of the tooltip instead of appending it to where it is currently being appended. I've given this a particular area to be appended just so that I know that it is, in fact, showing up(which it is), but I don't know how to get it into the tool tip. Any help is much appreciated. Oh, and this needs to be done in d3, which is partial to why I am asking this question -- I saw a similar question that wasn't implemented in pure d3, and I couldn't completely follow what was going on to emulate it in this example.
.on("mouseover", function(d)
{
tip.show(d);
var state = d.properties.name;
var men = d.properties.men;
var women = d.properties.women;
var dataset = [men, women];
var barHeight = 20;
var x = d3.scale.linear()
.domain([0, d3.max(dataset)])
.range([0, width/2]);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", barHeight * dataset.length);
var bar = chart.selectAll("g")
.data(dataset)
.enter().append("g")
.attr("transform", function(d, i)
{
return "translate(0," + i * barHeight + ")";
});
bar.append("rect")
.attr("width", x)
.attr("height", barHeight - 1);
bar.append("text")
.attr("x", function(d)
{
return x(d)/2+5;
})
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function(d)
{
return "$" + d;
});
})
Since you didn't shared the whole code to create the chart, this answer will deal with your question's title only:
How to create a chart inside a tooltip?
I'm not a d3.tip() user, since I create my own tooltips. But what you want is not complicated at all: As the tooltips are <div> elements, you can definitely add a SVG inside them.
However, you have to know where to create the SVG. So, in the following demo, I'm creating this d3.tip tooltip:
var tool_tip = d3.tip()
.attr("class", "d3-tip")
.offset([20, 120])
.html("<p>This is a SVG inside a tooltip:</p>
<div id='tipDiv'></div>");
//div ID here --^
The important part here is this: there is a inner <div> inside the d3.tip div, with a given ID (in that case, tipDiv). I'm gonna use that ID to create my SVG inside the tooltip:
selection.on('mouseover', function(d) {
tool_tip.show();
var tipSVG = d3.select("#tipDiv")
//select the div here--^
.append("svg")
//etc...
})
Here is the demo:
var svg = d3.select("body")
.append("svg")
.attr("width", 300)
.attr("height", 300);
var tool_tip = d3.tip()
.attr("class", "d3-tip")
.offset([20, 120])
.html("<p>This is a SVG inside a tooltip:</p><div id='tipDiv'></div>");
svg.call(tool_tip);
var data = [14, 27, 19, 6, 17];
var circles = svg.selectAll("foo")
.data(data)
.enter()
.append("circle");
circles.attr("cx", 50)
.attr("cy", function(d, i) {
return 20 + 50 * i
})
.attr("r", function(d) {
return d
})
.attr("fill", "teal")
.on('mouseover', function(d) {
tool_tip.show();
var tipSVG = d3.select("#tipDiv")
.append("svg")
.attr("width", 200)
.attr("height", 50);
tipSVG.append("rect")
.attr("fill", "steelblue")
.attr("y", 10)
.attr("width", 0)
.attr("height", 30)
.transition()
.duration(1000)
.attr("width", d * 6);
tipSVG.append("text")
.text(d)
.attr("x", 10)
.attr("y", 30)
.transition()
.duration(1000)
.attr("x", 6 + d * 6)
})
.on('mouseout', tool_tip.hide);
.d3-tip {
line-height: 1;
padding: 6px;
background: wheat;
border-radius: 4px solid black;
font-size: 12px;
}
p {
font-family: Helvetica;
}
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>
<p>Hover over the circles:</p>
I am trying to figure out how to show more text on a pie chart using mouseover than just the data that is bound to the pie. Below is my functional code
function Pie(value,names){
svg.selectAll("g.arc").remove()
var outerRadius = 100;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie();
var color = d3.scale.category10();
var arcs = svg.selectAll("g.arc")
.data(pie(value))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(950,80)");
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.on("mouseover",function(d,i) {
arcs.append("text")
.attr("dy", ".5em")
.style("text-anchor", "middle")
.style("fill", function(d,i){return "black";})
.text(d.data)
})
.on("mouseout", function(d) {
arcs.select("text").remove();
});}
The names array has the same length as the value array which is passed to the pie. I really hoped that something like this would work by replacing the above mouseover.
.on("mouseover",function(d,i) {
arcs.append("text")
.attr("dy", ".5em")
.style("text-anchor", "middle")
.style("fill", function(d,i){return "black";})
.text(function(d,i){return (d.data +" " + names[i]);)
})
But the only thing it does is to show all the elements of the values array stacked one on top of the other and the last element of the names array. It seems that i is always the last index in this case. How would I go about that? Could I show the text I want in another way? Thank you in advance.
First, the variable arcs is a data-bound d3 selection which represents all the arcs of the pie. So, by calling arcs.append, you are going to append a text element for each piece of your pie chart. I think you mean to only append one text element based on what you moused-over so re-write that as:
svg.append('text')
...
Second, in this expression:
.text(function(d,i){return (d.data +" " + names[i]);)
d and i in the mouseover function already represent the data and index of the pie slice being moused over. There is no reason to wrap this in another function and should be re-written:
.text(d.data +" " + names[i]);
Here's a complete example:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.arc path {
stroke: #fff;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.category10();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = [{
value: Math.random(),
}, {
value: Math.random(),
}, {
value: Math.random(),
}, {
value: Math.random(),
}, {
value: Math.random(),
}]
var names = ["A","B","C","D","E"];
var arcs = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
arcs.append("path")
.attr("d", arc)
.style("fill", function(d,i) {
return color(i);
})
.on("mouseover", function(d, i) {
console.log(d);
svg.append("text")
.attr("dy", ".5em")
.style("text-anchor", "middle")
.style("font-size", 45)
.attr("class","label")
.style("fill", function(d,i){return "black";})
.text(names[i]);
})
.on("mouseout", function(d) {
svg.select(".label").remove();
});
</script>
</body>
</html>
I am making a d3 graph and trying to put a border around my rect elements. The rect elements are appended to a cell and the text elements are appended to the same cell. Thus if I change the stroke in the rect I lose all the text for some reason, and if I change the stroke in the cell the borders and fonts change too.
This is a portion of my code for drawing the graph.
this.svg = d3.select("#body").append("div")
.attr("class", "chart")
.style("position", "relative")
.style("width", (this.w +this.marginTree.left+this.marginTree.right) + "px")
.style("height", (this.h + this.marginTree.top + this.marginTree.bottom) + "px")
.style("left", this.marginTree.left +"px")
.style("top", this.marginTree.top + "px")
.append("svg:svg")
.attr("width", this.w)
.attr("height", this.h)
.append("svg:g")
.attr("transform", "translate(.5,.5)");
this.node = this.root = this.nestedJson;
var nodes = this.treemap.nodes(this.root)
.filter(function(d) { return !d.children; });
this.tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) {
return "<span style='color:white'>" + (d.name+",\n "+d.size) + "</span>";
})
this.svg.call(this.tip);
var cell = this.svg.selectAll("g")
.data(nodes)
.enter().append("svg:g")
.attr("class", "cell")
.call(this.position)
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("click", function(d) { return this.zoom(this.node == d.parent ? this.root : d.parent); })
.style("border",'black');
var borderPath = this.svg.append("rect")
.attr("x", this.marginTree.left)
.attr("y", this.marginTree.top)
.attr("height", this.h - this.marginTree.top - this.marginTree.bottom )
.attr("width", this.w - this.marginTree.left - this.marginTree.right)
.style("stroke", 'darkgrey')
.style("fill", "none")
.style("stroke-width", '3px');
cell.append("svg:rect")
.attr("id", function(d,i) { return "rect-" + (i+1); })
.attr("class","highlighting2")
.attr("title", function(d) {return (d.name+", "+d.size);})
.attr("data-original-title", function(d) {return (d.name+",\n "+d.size);})
.attr("width", function(d) { return d.dx - 1; })
.attr("height", function(d) { return d.dy ; })
.on('mouseover', this.tip.show)
.on('mouseout', this.tip.hide)
.style("fill", function(d) {return coloring(d.color);});
cell.append("svg:text")
.attr("class", "treemap-text nameTexts")
.attr("id", function(d,i) { return "name-" + (i+1); })
.attr("x", cellMargin)
.attr("y", function(d) { return parseInt($('.treemap-text').css('font-size'))+cellMargin; })
.text(function(d) {return (d.name);});
cell.append("svg:text")
.attr("class", "treemap-text sizeTexts")
.attr("id", function(d,i) { return "size-" + (i+1); })
.attr("x", cellMargin)
.attr("y", function(d) { return 2*parseInt($('.treemap-text').css('font-size'))+2*cellMargin; })
.text(function(d) {return (d.size);});
Additionally, I thought about creating lines and drawing four lines around each rect element, but was wondering if there is an easier way. Thanks.
I didn't check fully through your source, it would also be helpful to work with jsbin, codepen, jsfiddle or other online platforms to show your problem.
Actually I think you just have misinterpreted the SVG presentation attributes and their styling with CSS. For SVG elements only SVG presentation attributes are valid in CSS. This means there is no border property as you have it in your code. Also note that for <text> elements the fill color is the font-body color and the stroke is the outline of the font. Consider that stroke and fill are inherited down to child element which means that if you have a rectangle with a stroke style and some containing text element that they will have the stroke applied as outline and you'd need to override the styles there.
Hope you can solve your issue.
Cheers
Gion