nvd3 angularjs fixed tooltip - d3.js

I'm trying to fix the graph but the tooltip is not fixed and have strange behavior where the tooltip start to float around the window.
I have tried to put in the nvd3.css the position fixed but didn't work:
.nvtooltip {
**position: fixed;**
background-color: rgba(255,255,255,1.0);
padding: 1px;
border: 1px solid rgba(0,0,0,.2);
z-index: 10000;
font-family: Arial;
font-size: 13px;
text-align: left;
pointer-events: none;
white-space: nowrap;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
Any advice?

Try to use fixedTop option of nv.models.tooltip model. This is inside the interactiveLayer chart option. So, you can set this up like:
nv.addGraph(function() {
var chart = nv.models.lineChart()
.useInteractiveGuideline(true) //required
...
//shoud be separated
chart.interactiveLayer.tooltip.fixedTop(100) //fixed distance from top
...
})
Here is a demo
Additional tooltip options (from the source):
content = null //HTML contents of the tooltip. If null, the content is generated via the data variable.
data = null // Tooltip data. If data is given in the proper format, a consistent tooltip is generated.
gravity = 'w' //Can be 'n','s','e','w'. Determines how tooltip is positioned.
distance = 50 //Distance to offset tooltip from the mouse location.
snapDistance = 25 //Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)
fixedTop = null //If not null, this fixes the top position of the tooltip.
classes = null //Attaches additional CSS classes to the tooltip DIV that is created.
chartContainer = null //Parent DIV, of the SVG Container that holds the chart.
tooltipElem = null //actual DOM element representing the tooltip.
position = {left: null, top: null} //Relative position of the tooltip inside chartContainer.
enabled = true //True -> tooltips are rendered. False -> don't render tooltips.

Related

how to set div max width in D3

how can I set the max width of a div within d3?
I tried
svg.append('div')
.attr('class','chart')
.attr("max-width",div_width)
.attr("height",div_height)
but it doesn't do the trick, however, if I set it in a css style with the class, it works,
div.chart {
margin : 2%;
overflow: auto;
background: rgba(51, 51, 51, 0.3);
max-width: 900px; // this works
}
I need the max width to be dynamic which is why I want to set it within d3.
Thanks for your help
I figured it out, it should be in (style) and as a string
svg.append('div')
.attr('class','chart')
.attr("max-width",div_width)
.attr("height",div_height)
should change to
svg.append('div')
.attr('class','chart')
.style("max-width",div_width+'px')
.attr("height",div_height)

Scrollbar amchart legend

I want a scrollbar for a label when the label more then the chart height. I mentioned in image where I want scrollbar. Actually sometime I have many labels therefore.
As described in the Documentation here:
https://www.amcharts.com/docs/v4/tutorials/chart-legend-in-an-external-container/#Making_legend_scrollable
You need to put the Legend into an external div thats inside a wrapper div.
The Div Structure:
<div id="legendwrapper">
<div id="legenddiv"></div>
</div>
Putting the legend in the external div:
var legendContainer = am4core.create("legenddiv", am4core.Container);
legendContainer.width = am4core.percent(100);
legendContainer.height = am4core.percent(100);
Then you can make it scrollable by styling it like this:
#legenddiv {
width: 150px;
}
#legendwrapper {
max-width: 120px;
overflow-x: none;
overflow-y: auto;
}
A simple way to do this with AMCharts 4
chart.legend = new am4charts.Legend();
chart.legend.position = "right"; // Positionning your legend to the right of the chart
chart.legend.scrollable = true: // Make it scrollable
See a full example as below :
https://codepen.io/team/amcharts/pen/eYmLvoR

how to make vertical column headers on automatic column generation?

how to make vertical column headers on automatic column generation in tabulator js library?
i did this, and it works just fine:
//define data
var tabledata = {!!$one!!}
//define table
var table = new Tabulator("#table-1", {
data:tabledata,
autoColumns:true,
layout:"fitColumns",
});
but, when i add "headerVertical:true" it doesn't make any change:
//define data
var tabledata = {!!$one!!}
//define table
var table = new Tabulator("#table-1", {
data:tabledata,
autoColumns:true,
headerVertical:true,
layout:"fitColumns",
});
can anyone help me with making vertical column headers while columns are generating automatically?
headerVertical only works if you define columns as per documentation, how ever you can use simple css to achieve that
https://jsfiddle.net/dota2pro/t0gw9jbp/5/
to rotate 180 degrees use CSS rotate
.tabulator-col-title {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
text-orientation: mixed;
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
padding-top: 20px;
/* if you use rotate change this to paddig-bottom*/
transform: rotate(180deg);
/* incase of rotation*/
}

Why would a dialog erase its content without refreshing?

I'm having this very strange problem where a window seems to be erasing its content and not redrawing it after erasing it. This dialog is derived from CDHtmlDialog, which I think is part of the problem. There is some sort of non-deterministic code execution happening resulting in some code being executed prior to others in certain cases and the opposite in others.
Message handlers that are involved are:
BEGIN_MESSAGE_MAP(CCalcDrillDownDlg, CDHtmlDialog)
ON_WM_PAINT()
END_MESSAGE_MAP()
BEGIN_EVENTSINK_MAP(CCalcDrillDownDlg, CDHtmlDialog)
ON_EVENT(CCalcDrillDownDlg, AFX_IDC_BROWSER, 250 /* BeforeNavigate2 */, _OnBeforeNavigate2b, VTS_DISPATCH VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PBOOL)
END_EVENTSINK_MAP()
The OnInitDialog() function is as follows:
BOOL CCalcDrillDownDlg::OnInitDialog()
{
SetHostFlags(DOCHOSTUIFLAG_FLAT_SCROLLBAR);
CDHtmlDialog::OnInitDialog(); // << will eventually call _OnBeforeNavigate2b()
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
LoadFromResource(IDR_CALC_DRILLDOWN); // << will eventually call _OnBeforeNavigate2b()
CString title = getStr2Ptr(22574);
SetWindowText(title);
ShowWindow(SW_SHOW);
return TRUE; // return TRUE unless you set the focus to a control
}
This is the OnPaint() function:
void CCalcDrillDownDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDHtmlDialog::OnPaint();
}
}
I've not put the contents of the _OnBeforeNavigate2b() function as it appears not to have anything to do with the redrawing system.
So what appears to happen is that sometimes, the dialog contents will be painted somehow prior to calling CCalcDrillDownDlg::OnPaint(). If this happens, then the call to CDHtmlDialog::OnPaint() will wipe the contents off the window.
Other times, the contents are not painted on the window prior to calling CCalcDrillDownDlg::OnPaint(). If this happens, then the call to CDHtmlDialog::OnPaint() will probably still wipe the contents off the window, which hasn't been painted yet, and then sometime after the call to CCalcDrillDownDlg::OnPaint(), it gets redrawn.
Spy++ doesn't capture any messages when the system properly redraws the window, so I've removed the messages generated from this question.
Does anyone have any idea as to how the redrawing is getting done and why the order gets foobarred sometimes?
Edit
Here is the contents of the IDR_CALC_DRILLDOWN resource:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Calculation Drilldown</title>
<style type="text/css">
body { overflow-y: auto; font-family: arial, Helvetica, sans-serif; font-size: 90%; }
a:link { color: black; }
a:visited { color: black; }
table { border-collapse: collapse; }
tr.runcache td { background-color: #B5B5B5; color: black; }
tr.runcache td a:link { color: black; }
tr.runcache td a:visited { color: black; }
tr.tracker td { background-color: white; color: black; }
tr.tracker td a:link { color: black; }
tr.tracker td a:visited { color: black; }
td.numericvalue { text-align: right; }
tr.paramTitle td { background-color: #4A4A4A; color: white; }
tr.resultTitle td { background-color: #4A4A4A; color: white; }
tr.resultTitle td a:link { color: white; }
tr.resultTitle td a:visited { color: white; }
tr.param td { background-color: white; color: black; }
tr.param td a:link { color: black; }
tr.param td a:visited { color: black; }
span.selection { background-color: #EBEBEB; }
</style>
</head>
<body>
<div id="calculation"></div>
<div id="details" style="padding-left: 0.1in; display: none;"></div>
</body>
</html>
Edit #2
Further investigation seems to show that the CDHtmlDialog class (or a base class thereof) will draw the window, irrespective of if my CCalcDrillDownDlg::OnPaint() calls CDHtmlDialog::OnPaint() or not, which is just weird and not intuitive. :(
Also, it seems that this is possibly threading related, as this seems to be dependant on how long it takes to render the window. If it takes a short time, it displays fine. If it takes a half a second or more, it screws up.
For the moment, I'm using a workaround where I have a m_bRepaint flag in the class which is initially set to true. Upon calling CCalcDrillDownDlg::OnPaint() and it is not iconic, I check the flag and force a resize. This is not optimal as it causes an initial flicker, but it at least it makes sure that the window's contents are drawn.
if (!m_bRepaint)
{
CDHtmlDialog::OnPaint();
}
else
{
CRect winRect;
GetWindowRect(&winRect);
SetWindowPos(NULL, 0, 0, winRect.Width() - 1, winRect.Height(), SWP_NOMOVE | SWP_NOZORDER);
SetWindowPos(NULL, 0, 0, winRect.Width() , winRect.Height(), SWP_NOMOVE | SWP_NOZORDER);
m_bRepaint = false;
}
Using Invalidate() does not work. I have to resize it to something other than it's current size and resize it back.
This CDHtmlDialog class is a PITA to work with and I wouldn't recommend anybody use it if they have a choice.
Ok, so it would seem that this is caused by the windows message queue not being deterministic, so it would seem that the underlying COM control is painting on it's DC prior to the WM_PAINT message.
To workaround the issue, I wait for the window to show itself by waiting for WM_WINDOWPOSCHANGED message, posting another application message which will then call Invalidate() and UpdateWindow(), thus forcing the redrawing of the window.
This technique is described here on Raymond Chen's blog "The Old New Thing".
Don't handle WM_ERASEBKGND.Set WM_CLIPCHILDREN style on the dialog.
ON_WM_ERASEBKGND()
...
BOOL CCalcDrillDownDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
}

Mouse hover applied to jQPLOT X AXIS TICKS

I am trying to add mouse hover function to my axis ticks.
what i want is to show long ticks full text only on hover else it would be showing only few characters . i am adding a hover event to .jqplot-xaxis-tick .But it doesnot even respond to hover.Please suggest !
.jqplot-xaxis-tick {
top: 0px;
/* initial position untill tick is drawn in proper place */
left: 15px;
/* padding-top: 10px;*/
vertical-align: top;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.jqplot-xaxis-tick :hover{
overflow:visible;
white-space: normal;
width: auto;
position: absolute;
background-color:yellow;
}
The hover is not detecting because of the z-index of the canvas which lies on top of the whole chart. I did the following and now it's shorten the tootip by CSS ellipsis and show the tooltip with full name on hover.
Based on the Gyandeep's answer, the exact JS and CSS I used are,
Javascript:
$('div.jqplot-xaxis-tick').each(function (i, obj) {
$(this).prop('title', ($(this).text()));
$(this).css('z-index', 999); // this is important otherwise mouseover won't trigger.
});
CSS:
.jqplot-xaxis .jqplot-xaxis-tick {
position: absolute;
white-space: pre;
max-width: 92px; // Change it according to your need
overflow: hidden;
text-overflow: ellipsis;
}
The JavaScript part needs to be executed after every rendering of chart. It's better to put them right after plotting the chart and may in the AJAX success handler.
I managed to add a tooltip kindof feature to axis ticks.When I hover upon them it shows a separate box with full text else only 3-4 characters are shown.
The code is something like this
$($('.jqplot-xaxis-tick')[i]).bind('mouseover', function () {
// var m= '-webkit-marquee';
$($('.jqplot-xaxis-tick')[i]).css('white-space','pre-line');
$($('.jqplot-xaxis-tick')[i]).css('overflow','visible');
$($('.jqplot-xaxis-tick')[i]).css('width','auto');
$($('.jqplot-xaxis-tick')[i]).css('position','absolute');
$($('.jqplot-xaxis-tick')[i]).css('background-color','#666666');
$($('.jqplot-xaxis-tick')[i]).css('color','white');
$($('.jqplot-xaxis-tick')[i]).css('top','-45px');
// $($('.jqplot-xaxis-tick')[i]).css('overflow-x',m);
// console.log($($('.jqplot-xaxis-tick')[i]).text());
}).bind('mouseout', function () {
//var m= '';
//$($('.jqplot-xaxis-tick')[i]).css('overflow-x',m);
$($('.jqplot-xaxis-tick')[i]).css('white-space','nowrap');
$($('.jqplot-xaxis-tick')[i]).css('overflow','hidden');
$($('.jqplot-xaxis-tick')[i]).css('width','50');
$($('.jqplot-xaxis-tick')[i]).css('background-color','');
$($('.jqplot-xaxis-tick')[i]).css('color','grey');
$($('.jqplot-xaxis-tick')[i]).css('top','0px');
});
Here's the solution I'm using to display monthly high and low temperatures. Hovering over the x-axis tick will display an alert with the active month name and temps.
// Set up hover function
$('#monthlyTemps .jqplot-xaxis-tick').hover(function () {
setActiveColumn($(this));
});
// Set active column
function setActiveColumn(sender) {
// Display values
var monthName = sender.text();
var monthIndex = monthNames.indexOf(monthName);
var monthLowTemp = getMonthLowTemp(monthIndex);
var monthHighTemp = getMonthlHighTemp(monthIndex);
alert(monthName + ': ' + monthLowTemp + ' / ' + monthHighTemp);
}
// Get month low temp
function getMonthLowTemp(monthIndex) {
var value= $("#monthlyTemps .jqplot-point-label.jqplot-series-0.jqplot-point-" + monthIndex).text();
return value;
}
// Get month high temp
function getMonthlyHighTemp(monthIndex) {
var value= $("#monthlyTemps .jqplot-point-label.jqplot-series-1.jqplot-point-" + monthIndex).text();
return value;
}
var monthNames = new Array(12);
monthAbbreviations[0] = "Jan";
monthAbbreviations[1] = "Feb";
monthAbbreviations[2] = "Mar";
monthAbbreviations[3] = "Apr";
monthAbbreviations[4] = "May";
monthAbbreviations[5] = "Jun";
monthAbbreviations[6] = "Jul";
monthAbbreviations[7] = "Aug";
monthAbbreviations[8] = "Sep";
monthAbbreviations[9] = "Oct";
monthAbbreviations[10] = "Nov";
monthAbbreviations[11] = "Dec";

Resources