JQuery Dialog Close Event - jquery-dialog

$("#termSheetPrinted").dialog({
autoOpen: false,
resizable: true,
height: $(window).height() - 50,
width: $(window).width() - 50,
position: 'center',
title: 'Term Sheet',
beforeClose: function(event, ui) { $("#termSheetPrinted").html(''); },
modal: true,
buttons: {
"Print": function () {
$("#termSheetPrinted").jqprint();
},
"Cancel": function () {
$("#termSheetPrinted").html('');
$(this).dialog("close");
}
}
});
So, when I click 'Cancel', I can generate the dialog right over again and everything looks fine. If I click the 'X' in the upper right corner and generate it again, it doubles up, having not been cleared from the last time.
I tried adding the beforeClose event to clear the HTML, however it doesn't seem to be working.
How can I get it to clear and close properly from both 'Cancel', and hitting the 'X'?

Seems to work if I bind it to close instead.
Shouldn't this work both ways though?

Related

Chartjs: Set minimum value for zoom on drag and proper user feedback

I am using Chartjs 4.0.1 and chartjs-plugin-zoom 2.0.0 and my chart look like this:
I have set the drag option to be enabled so the user can draw a rectangle to zoom in. Also I have set the zoom mode to 'x'. So the user can only zoom in on the x axis but not on the y axis.
Now I want to limit how far the user can zoom in, to a timespan of one month. I have managed to do that when using the mousewheel to zoom in. But I dont know how to achive the same when using the drag option. I have it configured like this:
drag:{
enabled: true,
backgroundColor:'rgba(180,180,180,0.4)',
threshold: 25,
}
The threshold seems to be my best option to a limit. However that is in pixels and it only says how wide the drawn rectangle has to be for a zoom to occur.
I am already using the onZoomStart callback to check how far the chart is zoomed in and based on that decide if the user can zoom in even more. But apparently that callback is only executed when zooming by mousewheel but not when dragging. So I think I would need to be able to set the threshold of the drag object dynamically. Does anyone know how to do that?
Also I was wondering, is it possible to change the border color of the rectangle when dragging to show the user if it is big enough for a scroll to occur?
The standard solution seems to be to set a limits:{x:{minRange:...}} option. It took me a while to realise where that option should be inserted.
Below is a code snippet with some data resembling yours and a minRange set to 90 days (so I can skip adjusting the tick interval).
Also, there's a hack that changes the color of the drag rectangle to red if the interval is less than the 90 days. It can easily be adapted to completely reject the zoom for less than the desired interval, instead of the current standard behavior which is to adjust (extend) the interval until it is equal to minRange.
The same in this fiddle.
const nPoints = 400,
t0 = Date.parse("2018-06-02T00:00:00Z"),
dt = 2.5*365/nPoints*24*3600*1000;
const data = Array.from(
{length: nPoints},
(_, i)=>({
"timestamp":(t0+dt*i),
value: 80*Math.sin(i*Math.PI/nPoints)+2*Math.random()
})
);
let mouseMoveHandler = null;
chart = new Chart(document.getElementById("myChart"), {
type: 'line',
data: {
datasets: [{
label: "Count",
//pointStyle: false,
pointRadius: 2,
showLine: true,
fill: true,
tension: 0,
borderColor: '#aa6577',
//pointRadius: 4,
//pointBorderWidth: 1,
//pointBackgroundColor: '#7265ce',
data: data
}]
},
options: {
parsing: {
xAxisKey: 'timestamp',
yAxisKey: 'value'
},
spanGaps: false,
responsive: false,
scales: {
x: {
bounds: 'ticks',
type: 'time',
time: {
unit: 'month',
},
title: {
display: false,
text: 'time'
},
ticks: {
display: true,
color: '#cecece'
}
},
y: {
type: 'linear',
display: true,
min: -10,
max: 140,
ticks: {
autoSkip: true,
color: '#cecece'
},
grid:{
color: ctx => ctx.tick.value === 0 ? '#000' : '#ddd',
lineWidth: ctx => ctx.tick.value === 0 ? 3 : 1,
},
title: {
display: false,
text: 'Count',
align: 'end'
},
}
},
plugins:{
legend:{
display: false
},
zoom: {
zoom: {
drag: {
enabled: true,
backgroundColor:'rgba(180,180,180,0.4)',
},
mode: 'x',
onZoomStart({chart, event}){
const x0 = chart.scales.x.getValueForPixel(event.clientX);
if(event.type==="mousedown"){
mouseMoveHandler = function(e){
if(
Math.abs(chart.scales.x.getValueForPixel(e.clientX) - x0) <
chart.options.plugins.zoom.limits.x.minRange
){
chart.options.plugins.zoom.zoom.drag.backgroundColor = 'rgba(255,180,180,0.4)';
}
else{
chart.options.plugins.zoom.zoom.drag.backgroundColor = 'rgba(180,180,180,0.4)';
}
};
chart.canvas.addEventListener("mousemove", mouseMoveHandler);
chart.canvas.addEventListener("mouseup", function(){
if(mouseMoveHandler){
chart.canvas.removeEventListener("mousemove", mouseMoveHandler);
mouseMoveHandler = null;
}
}, {once: true});
}
},
onZoomComplete({chart}){
if(mouseMoveHandler){
chart.canvas.removeEventListener("mousemove", mouseMoveHandler);
mouseMoveHandler = null;
}
document.querySelector('#zoom').innerText = chart.getZoomLevel().toFixed(1)+'x';
document.querySelector('#xSpan').innerText =
Math.round((chart.scales.x.max-chart.scales.x.min)/24/3600/1000)+'days';
}
},
limits:{
x: {
minRange: 90 * 24* 3600 * 1000
}
}
}
}
}
});
document.querySelector('#resetZoom').addEventListener('click', function(){chart.resetZoom();});
document.querySelector('#xSpan').innerText = Math.round((chart.scales.x.max-chart.scales.x.min)/24/3600/1000)+'days';
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.0.1/chart.umd.min.js"
integrity="sha512-HyprZz2W40JOnIBIXDYHCFlkSscDdYaNe2FYl34g1DOmE9J+zEPoT4HHHZ2b3+milFBtiKVWb4sorDVVp+iuqA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/2.0.0/chartjs-plugin-zoom.min.js"
integrity="sha512-B6F98QATBNaDHSE7uANGo5h0mU6fhKCUD+SPAY7KZDxE8QgZw9rewDtNiu3mbbutYDWOKT3SPYD8qDBpG2QnEg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js">
</script>
<canvas id="myChart" style="height:500px; width: 90vw"></canvas>
<button id="resetZoom">Reset zoom</button> <br>
zoom: <span id="zoom">1x</span><br>
X axis span: <span id="xSpan"></span>

how to show text inside a chart - pie and doughnut?

I have tried a lot of it, but nothing seems to be working as expected.
I need to show the text inside the pie chart.
For the above, I tried using chartjs-plugin-datalabels but then used a formatter to change a value to a value with a percentage.
formatter: function(value:any, context:Context) {
return Math.floor(value) + '%';
},
But that affected both the data point (i.e: [11,200] is by data, I only need to add a percentage to the first data point and not to the second. Show 11% and 200.)
Code:
import ChartDataLabels,{Context} from 'chartjs-plugin-datalabels';
ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);
export const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
datalabels: {
formatter: function(value:any, context:Context) {
return Math.floor(value) + '%';
},
color:"white",
font: {
size: 16,
weight:'bold'
}
},
title: {
display: true,
},
legend: {
display: false,
},
},
};
function MyChart(){
return(
<Pie data={dataChart} options={options} />
)
}
In the above code options in the Pie, the component shows a typescript error while using chartjs-plugin-datalabels library.
The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Omit<ChartProps<"doughnut", number[], unknown>, "type"> & { ref?: ForwardedRef<ChartJSOrUndefined<"doughnut", number[], unknown>> | undefined; }'
2: I need to show text in the center of a Doughnut chart but seems impossible with the library and reactchartjs2 don't have a feature to show text in charts. Tried a possible solution at Add text inside the Doughnut chart of the React-Chartjs-2 box to react but none helped.

Angular CharJS option tooltip label did not work

I have a component code like below
changeData() {
const changedData = this.getData();
this.chartData = Object.assign({}, changedData);
this.lineTooltips = this.getLineTooltips();
this.chartOptions = {
tooltips: {
enabled: true,
callbacks: {
label: function(tooltipItem, data) {
return (data.tooltips[tooltipItem.index]).split('#');
},
}
}
}
}
and also HTML file
<div class="chartStyle">
<p-chart type="line" [data]="chartData" responsive="true" [options]="chartOptions" (onDataSelect)="selectData($event)"></p-chart>
The chart can load the line and data, but I hover to each item on the chart, the callback function did not work to load tooltip.
If you log data.tooltips you will see its undefined, and since you try to read things from it it will throw an error and not draw anything.
Looking at the documentation I think you have to replace data.tooltips with data.datasets. (https://www.chartjs.org/docs/latest/configuration/tooltip.html#label-callback)
The best thing you can do is just log both tooltipItem and data and go through the objects to see how you can combine them to get to the point you need and then insert that in your callback.

I want to hide the label in a tooltip because it shows undefined

I am using chart.js to show a line chart. How can I hide a tooltip label for a chart.js line chart? The label in the tooltip is showing undefined so I want to hide the label (please see the screenshot)?
Perhaps there is a way to modify tooltip where I can show only the legends value in tooltip? My code is as follows:
myLine = new Chart(ctx).Line(lineChartData, {
type: 'line',
responsive: true,
scaleShowGridLines : false,
bezierCurve : false,
animationEasing: "linear",
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
showTooltips: true,
scaleLineColor: "rgba(0,0,0,.8)",
});
Just set the tooltipTitleFontSize to 0 in your options.
Preview
Script
myLine = new Chart(ctx).Line(lineChartData, {
...
tooltipTitleFontSize: 0
});
I know I am late, but I guess it still has merit to add this one.
check this : https://stackoverflow.com/a/44632748/12061669
It uses a function to hide the title:
options:{
tooltips:{
callbacks:{
title: ()=>{}
}
}
}
Setting the title's font size to zero is not ideal as you will still see an (ugly) extra space on top of the tooltip, as if the title line is still there - which honestly is what you'd expect.
Instead, I used Yumin Gui's answer but had to return null for it to work:
`
tooltips: {
callbacks: {
title: () => null,
},
},
The result is exactly as in the pie charts (which does not have a title in its default tooltips).
To hide the tooltip title/label, it should be added in the options object for that chart as follows:
options: {
plugins: {
tooltip: {
callbacks: {
title : () => null // or function () { return null; }
}
}
}
}
Do refer to the documentation to understand better that it should be handled with a custom callback function, and it is not a config that can be set in options directly.
The accepted answer won't work in newer versions of chart.js, as Aman said in comments, what you can use now is this:
tooltips: { titleFontSize: 0 }
Example:
var bar_chart = document.getElementById('bar_canvas').getContext('2d');
window.myBar = new Chart(bar_chart, {
type: 'bar',
data: bar_chart_data,
options: {
tooltips: {
titleFontSize: 0,
bodyFontSize: 14,
}
}
});

Button appears on hover

I have a box. when you put your mouse over the box, a button appears on top of the box. the hover function works in such a way that it doesn't recognize that the mouse is still on top of the box. how can I solve it?
//I create the paper
var paper = Raphael(0, 0, 500,500);
//I add the box
var box = paper.add([{
type: "rect",
x: 100,
y: 100,
width: 100,
height: 100,
fill: '#000',
}])
// I declare a varible for the button
var button
//I add hover functions to the box.
//first function: when the mouse is on, create a red circle and add an
//onclick event to the circle
box.hover(function () {
button = paper.circle(150, 150, 25).attr({ 'fill': 'red' })
button.click(function () { alert("You clicked me!")})
},
//second function: when the mouse leaves the box, remove the circle
function () {
button.remove()
})
Here is an example
http://jsfiddle.net/V4E4Q/
You will have to deal with events from different objects one way or another, either I guess with a couple of handlers, or with one that has event propagation and handling possibly, or group with a set. The current event is coming from the button when its displayed, so the event logic doesn't quite make sense as it is. So you could add a handler to the button as well (edit, or use a set for example).
One example would be...
var button = paper.circle(150, 150, 25).attr({ 'fill': 'red' });
button.hide();
button.click( function() { alert("button clicked"); } );
box.mouseout( function() { button.hide() });
button.mouseover( function() { button.show(); });
box.mouseover(function () { button.show(); } );
I'm not sure if this is the most efficient way, but it should work. jsfiddle here http://jsfiddle.net/V4E4Q/1/
Edit: Another possibly cleaner way could be to group the elements into a set and handle the click. Here is a modified example http://jsfiddle.net/V4E4Q/3/