ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  [MFC]FLICKERING.
Posted by Kaiden on Jul-17-2013 22:30
HELLO PETER AGAIN.

SORRY FOR BUGGING YOU. i AM JUST ASKING A QUESTION ON EACH POSTS SO THAT
PEOPLE CAN SEE THE TITLE AND GET HELP IF NEEDED:)
AND OF COURSE MAKES ME EASIER TO WRITE A QUESTION AT A TIME.

WITH MY APP, THERE ARE SOME FLICKERINGS.

FIRST IT WAS BAD. MOUSE MOVE ON PLOT AREA MADE FLICKER WHEN MOUSE WAS
STILL AND NOT MOVING.
I USED THE SAMPLE CODES FROM TRACK LINE LEGEND SAMPLE, LATER ON I DIDN' NEED
THE TRACK LINE, SO I DELETED ALL THE TRACKLINELEGEND FUNCTION CALLINGS.

STILL MOUSEMOVEPLOTAREA WAS CALLED, SO I DELETED THE PART WHERE IT CALLS
"DRAWCHART", IN MY CASE THIS IS WHERE THE PLOT IS DRAWN.

SO NOW, MOUSEMOVE AROUND THE PLOT AREA DOESN'T CAUSE FLICKER.
BUT WHEN ZOOMING IN AND OUT OR MOVNIG THE CHART AROUND WHEN ZOOMED IN
CAUSES THE FLICKER.

I TRIED LOOKING THROUGH YOUR PREVIOUS ANSWERS, THE DOULBLE BUFFERING AND ALL
THAT.

BUT THE SMAPLE CODES DOES NOT HAVE FLICKER, SO I ASSUME IT HAS NOTHING TO DO
WITH DOUBLE BUFFERING. DOULBLE BUFFERING COULD WORK, NOT I DON'T THAT IS THE
PROPER WAY TO SOLVE THIS PROBLEM.

I'LL BE WAITING FOR YOUR REPLY PETER,
THANK YOU IN ADVANCE!!

TAKE CARE!

BEST REGARDS,
KAIDEN.


//HERE ARE THE CODES// SAME CODE FROM PREVIOUS QUESTION.

void initChartViewer(CChartViewer *viewer)
{
int arrFoundSize = arrFindVec.GetSize();

dTitle = new double*[m_pDoc->iLineCount-7];
arrTempData.SetSize(m_pDoc->iLineCount-7);

m_labels = new char*[arrFoundSize];
CString strTmpLabels;

for(int iDataIdx = 7; iDataIdx != m_pDoc->iLineCount; iDataIdx++)
{
dTitle[iDataIdx-7] = new double[arrFoundSize]; // init data fields.
}

for(int i=0; i<arrFindVec.GetSize(); i++)
{
if(m_MaxiDiffCount == 1)
{
strTmpLabels = _T("");

for(int j=0; j<m_MaxiDiffCount; j++)
{
strTmpLabels +=m_strX_Axis[i].GetAt(j);
if( j != m_MaxiDiffCount - 1 )
{
strTmpLabels += _T(" ");
}
}
}
else if(m_MaxiDiffCount > 1)
{
strTmpLabels = _T("");
for(int j=0; j<m_arrSameWordsDiffCountTitle[0].GetSize(); j++)
{
strTmpLabels += m_strX_Axis[i].GetAt(j);
if( j != m_arrSameWordsDiffCountTitle[0].GetSize() - 1 )
{
strTmpLabels += _T(" ");
}
}
}

int strLen = strTmpLabels.GetLength();
m_labels[i] = new char[strLen+1];
WideCharToMultiByte(CP_ACP, 0,strTmpLabels, -1, m_labels[i], strLen+1,
NULL, NULL);

for(int iDataIdx = 7; iDataIdx != m_pDoc->iLineCount; iDataIdx++)
{
strTmp = m_pDoc->vec2dStr[iDataIdx][arrFindVec.GetAt(i)];
dTitle[iDataIdx-7][i] = _wtof(strTmp);
}
}

    // Set the full x range to be the duration of the data
    viewer->setFullRange("x", 0, 0);
//viewer->setFullRange("x", m_timeStamps[0], m_timeStamps[m_timeStamps.len -
1]);

    // Initialize the view port to show the latest 20% of the time range
    m_chartView.setViewPortWidth(1);
    m_chartView.setViewPortLeft(1 - m_chartView.getViewPortWidth());

    // Set the maximum zoom to 10 points
    m_chartView.setZoomInWidthLimit(10.0 / arrFindVec.GetSize());
//m_chartView.setZoomInWidthLimit(10.0 / m_timeStamps.len);

    // Initially set the mouse to drag to scroll mode.
    m_PointerPB.SetCheck(1);
    m_chartView.setMouseUsage(Chart::MouseUsageScroll);
}


void OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();

// search button
CButton* pBtnSearch = (CButton*)GetDlgItem(IDC_BUTTON1);
CButton* pBtnDraw = (CButton*)GetDlgItem(IDC_BUTTON_DRAW);
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
CButton* pBtnEdit = (CButton*)GetDlgItem(IDC_BUTTON_TITLE_EDIT);
CEdit* pStaticTitle = (CEdit*)GetDlgItem(IDC_STATIC_TITLE);

CButton* pBtnPointer = (CButton*)GetDlgItem(IDC_PointerPB);
CButton* pBtnZoomIn = (CButton*)GetDlgItem(IDC_ZoomInPB);
CButton* pBtnZoomOut = (CButton*)GetDlgItem(IDC_ZoomOutPB);


pBtnSearch->EnableWindow(FALSE);
pBtnDraw->EnableWindow(FALSE);
pEdit->EnableWindow(FALSE);
pBtnEdit->EnableWindow(FALSE);
pStaticTitle->EnableWindow(FALSE);

pBtnPointer->EnableWindow(FALSE);
pBtnZoomIn->EnableWindow(FALSE);
pBtnZoomOut->EnableWindow(FALSE);

// loaded files info
m_ListRead.InsertColumn(0, _T("Name"), LVCFMT_LEFT, 185);
m_ListRead.InsertColumn(1, _T("Modified"), LVCFMT_LEFT, 100);
m_ListRead.InsertColumn(2, _T("Size"), LVCFMT_LEFT, 50);
m_ListRead.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);


// draw blank chart.
m_pChart = new XYChart(800, 600, 0xF0F0F0, 0xffffff, 1);
m_pChart->setRoundedFrame();

    m_pChart->setPlotArea(50, 75, 700, 400, 0xffffff, -1, -1, 0xcccccc, 0xcccccc);

    m_pChart->addLegend(30, 20, false, "arialbd.ttf", 9)-
>setBackground(Chart::Transparent);

m_chartView.setChart(m_pChart);

delete m_pChart;
//-----------------------------------------------------------------------------------
-----------
// StaticText Test
StaticTextButton.SubclassDlgItem(IDC_STATIC_TITLE, this);
//-----------------------------------------------------------------------------------
-----------

UpdateData(TRUE);


ListBoxColoredBy = (CListBox*)GetDlgItem(IDC_LIST_COLORED_BY); // get
ListBoxColoredBy
ListBoxColoredBy->ShowWindow(SW_HIDE);

m_ListRead.SetExtendedStyle( LVS_EX_CHECKBOXES ); // add CheckBox in
ListControl

//-----------------------------------------------------------------------------------
---------------------------
static const int m_iColorTable[100] =
{ 0xFF0000, 0x9ACD32, 0x8B008B, 0x800000, 0x5F9EA0, 0xA52A2A, 0xA0522D,
0x8B4513, 0xCD5C5C, 0xBC8F8F,
0xF08080, 0xFA8072, 0xE9967A, 0xFF7F50, 0xFF6347, 0xF4A460, 0xFFA07A,
0xCD853F, 0xD2691E, 0xFF4500,
0xFFA500, 0xFF8C00, 0xD2B48C, 0xFFDAB9, 0xFFE4C4, 0xFFE4B5,
0xFFDEAD, 0xF5DEB3, 0xDEB887, 0xB8860B,
0xDAA520, 0xFFD700, 0xFFFF00, 0xFAFAD2, 0xEEE8AA, 0xF0E68C,
0xBDB76B, 0x7CFC00, 0xADFF2F, 0x7FFF00,
0x00FF00, 0x32CD32, 0xDC143C, 0x808000, 0x6B8E23, 0x556B2F, 0x228B22,
0x006400, 0x008000, 0x2E8B57,
0x3CB371, 0x8FBC8F, 0x90EE90, 0x98FB98, 0x00FF7F, 0x00FA9A, 0x008080,
0x008B8B, 0x20B2AA, 0x66CDAA,
0x8B0000, 0x4682B4, 0x7FFFD4, 0xB0E0E6, 0xAFEEEE, 0xADD8E6, 0xB0C4DE,
0x87CEEB, 0x87CEFA, 0x48D1CC,
0x40E0D0, 0x00CED1, 0x00FFFF, 0x00FFFF, 0x00BFFF, 0x1E90FF, 0x6495ED,
0x4169E1, 0x0000FF, 0x0000CD,
0x000080, 0x00008B, 0x191970, 0x483D8B, 0x6A5ACD, 0x7B68EE, 0x9370DB,
0x9932CC, 0x9400D3, 0x8A2BE2,
0xBA55D3, 0xDDA0DD, 0xE6E6FA, 0xD8BFD8, 0xDA70D6, 0xEE82EE, 0x4B0082,
0xB22222, 0x800080, 0xC71585
};

for(int k=0; k<100; k++)
{
m_aryHexColor.Add( m_iColorTable[k] );
}
//-----------------------------------------------------------------------------------
---------------------------

}
//
// The ViewPortChanged event handler. This event occurs if the user scrolls or zooms in
or
// out the chart by dragging or clicking on the chart. It can also be triggered by calling
// CChartViewer.updateViewPort.
//
void OnViewPortChanged()
{
//MessageBox(_T("on view port changed"));
    // In addition to updating the chart, we may also need to update other controls that
    // changes based on the view port.
    updateControls(&m_chartView);

    // Update the chart if necessary
    if (m_chartView.needUpdateChart())
        drawChart(&m_chartView);

    // We need to update the track line too. If the mouse is moving on the chart (eg. if
    // the user drags the mouse on the chart to scroll it), the track line will be updated
    // in the MouseMovePlotArea event. Otherwise, we need to update the track line here.

/*
if (!m_chartView.isInMouseMoveEvent())
{
       // trackLineLegend((XYChart *)m_chartView.getChart(),
m_chartView.getPlotAreaMouseX());
        m_chartView.updateDisplay();
    }*/
}

//
// Draw track cursor when mouse is moving over plotarea
//
void OnMouseMovePlotArea()
{

//MessageBox(_T("On mouse move plot area"));
    // Get the focus to ensure being able to receive mouse wheel events
if(!nFlag == 0)
{
//m_nMouseMove = 1;
m_chartView.SetFocus();

//trackLineLegend((XYChart *)m_chartView.getChart(),
m_chartView.getPlotAreaMouseX());
// m_chartView.updateDisplay();
}
}

void updateControls(CChartViewer *viewer)
{
// we need to update the scroll bar to reflect the view port position and
// width of the view port.

//MessageBox(_T("update control"));
m_HScrollBar.EnableWindow(viewer->getViewPortWidth() < 1);
if (viewer->getViewPortWidth() < 1)
{
SCROLLINFO info;
info.cbSize = sizeof(SCROLLINFO);
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = 0x1fffffff;
info.nPage = (int)ceil(viewer->getViewPortWidth() * (info.nMax - info.nMin));
info.nPos = (int)(0.5 + viewer->getViewPortLeft() * (info.nMax - info.nMin))
+ info.nMin;
m_HScrollBar.SetScrollInfo(&info);
}
}
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: Add your message handler code here and/or call default

//return CFormView::OnMouseWheel(nFlags, zDelta, pt);
// Process the mouse wheel only if the mouse is over the plot area
if (!m_chartView.isMouseOnPlotArea())
return FALSE;

    // We zoom in or out by 10% depending on the mouse wheel direction.
double newVpWidth = m_chartView.getViewPortWidth() * (zDelta > 0 ? 0.8 : 1 /
0.8);
double newVpHeight = m_chartView.getViewPortHeight() * (zDelta > 0 ? 0.8 : 1 /
0.8);

    // We do not zoom beyond the zoom width or height limits.
    newVpWidth = max(m_chartView.getZoomInWidthLimit(), min(newVpWidth,
        m_chartView.getZoomOutWidthLimit()));
    newVpHeight = max(m_chartView.getZoomInHeightLimit(), min(newVpWidth,
        m_chartView.getZoomOutHeightLimit()));

if ((newVpWidth != m_chartView.getViewPortWidth()) ||
(newVpHeight != m_chartView.getViewPortHeight()))
{
// Set the view port position and size so that the point under the mouse
remains under
// the mouse after zooming.

double deltaX = (m_chartView.getPlotAreaMouseX() -
m_chartView.getPlotAreaLeft()) *
(m_chartView.getViewPortWidth() - newVpWidth) /
m_chartView.getPlotAreaWidth();
m_chartView.setViewPortLeft(m_chartView.getViewPortLeft() + deltaX);
m_chartView.setViewPortWidth(newVpWidth);

double deltaY = (m_chartView.getPlotAreaMouseY() -
m_chartView.getPlotAreaTop()) *
(m_chartView.getViewPortHeight() - newVpHeight) /
m_chartView.getPlotAreaHeight();
m_chartView.setViewPortTop(m_chartView.getViewPortTop() + deltaY);
m_chartView.setViewPortHeight(newVpHeight);

    m_chartView.updateViewPort(true, false);
}

return TRUE;
}

drawChart(){
// TODO: Add your control notification handler code here
int arrFoundSize = arrFindVec.GetSize();

dTitle = new double*[m_pDoc->iTotalRowCount];
arrTempData.SetSize(m_pDoc->iTotalRowCount); // 데이터 값을 받을 임의의 배
열의 크기 설정.

m_labels = new char*[arrFoundSize];
CString strTmpLabels;

for(int iDataIdx = 0; iDataIdx != m_pDoc->iTotalRowCount; iDataIdx++)
{
dTitle[iDataIdx] = new double[arrFoundSize]; // init data fields.
}

for(int i=0; i<arrFindVec.GetSize(); i++)
{
if(m_MaxiDiffCount == 1)
{
strTmpLabels = _T("");
// 타이틀 문자열 중 다른 개수 만큼 배열에 저장.
for(int j=0; j<m_MaxiDiffCount; j++)
{
strTmpLabels +=m_strX_Axis[i].GetAt(j);
if( j != m_MaxiDiffCount - 1 )
{
strTmpLabels += _T(" ");
}
}
}
else if(m_MaxiDiffCount > 1)
{
strTmpLabels = _T("");
// 타이틀 문자열 중 다른 개수 만큼 배열에 저장.
for(int j=0; j<m_arrSameWordsDiffCountTitle[0].GetSize(); j++)
{
strTmpLabels += m_strX_Axis[i].GetAt(j);
if( j != m_arrSameWordsDiffCountTitle[0].GetSize() - 1 )
{
strTmpLabels += _T(" ");
}
}
}

int strLen = strTmpLabels.GetLength();
m_labels[i] = new char[strLen+1];
WideCharToMultiByte(CP_ACP, 0,strTmpLabels, -1, m_labels[i],
strLen+1, NULL, NULL);

for(int iDataIdx = 0; iDataIdx != m_pDoc->iTotalRowCount; iDataIdx++)
{
strTmp = m_pDoc->vec2dStr[ ( m_pDoc-
>m_fileDataSeperate.GetAt(0) ) + iDataIdx ][arrFindVec.GetAt(i)];
dTitle[iDataIdx][i] = _wtof(strTmp);
}
}
//------------------------------------------------------------------------
--------------------------------------

m_pChart = new XYChart(800, 600, 0xf0f0f0, 0xaaaaaa);

//m_pChart->getHeight() - 35, 0xf0f6ff, 0xa0c0ff), -1, Chart::Transparent, 0xffffff,
0xffffff);
m_pChart->setPlotArea(55, 90, m_pChart->getWidth() - 90, m_pChart-
>getHeight() - 160, 0xf0f0f0, -1, Chart::Transparent, 0x7F7F7F, 0x7F7F7F);

//**
m_pChart->addLegend(30, 20, false, "arialbd.ttf", 9)-
>setBackground(Chart::Transparent);

// As the data can lie outside the plotarea in a zoomed chart, we need
enable clipping.
m_pChart->setClipping();

// Add a title to the chart using 18 pts Times New Roman Bold Italic font
m_pChart->addTitle(m_graphTitle, "timesbi.ttf", 18);

//**
m_pChart->xAxis()->setLabelStyle("arialbd.ttf", 7, 0x008000)-
>setFontAngle(45);
m_pChart->xAxis()->setLabels(StringArray(m_labels, arrFoundSize));
//**

// Set legend icon style to use line style icon, sized for 8pt font
m_pChart->getLegend()->setLineStyleKey();
m_pChart->getLegend()->setFontSize(8);


// Set the axis stem to transparent
m_pChart->xAxis()->setColors(Chart::Transparent);
m_pChart->yAxis()->setColors(Chart::Transparent);

//**
// Display 1 out of 3 labels on the x-axis.
m_pChart->xAxis()->setLabelStep(1);
//**


// Add a line layer for the lines, using a line width of 2 pixels
vector< LineLayer* > vecLineLayer;
for(int iLayerIdx = 0; iLayerIdx != m_pDoc->iTotalRowCount; iLayerIdx++)
{
LineLayer* layer = m_pChart->addLineLayer();
layer->setLineWidth(2);
layer->setFastLineMode();
vecLineLayer.push_back(layer);
}

//------------------------------------------------------------------------
for(int i=0; i<m_pDoc->iTotalRowCount; i++)
{
//vecLineLayer[i]->addDataSet(DoubleArray(dTitle[i], arrFoundSize),
m_aryTotalCountColor.GetAt(i), "DATA");
vecLineLayer[i]->addDataSet(DoubleArray(dTitle[i], arrFoundSize),
m_aryTotalCountColor.GetAt(i));//, "DATA");
}


m_chartView.syncLinearAxisWithViewPort("x", m_pChart->xAxis());
m_chartView.syncLinearAxisWithViewPort("y", m_pChart->yAxis());
m_chartView.setScrollDirection(Chart::DirectionHorizontalVertical);
m_chartView.setZoomDirection(Chart::DirectionHorizontalVertical);


m_chartView.setChart(m_pChart);

for(int i=0; i<m_pDoc->iTotalRowCount; i++)
{
delete[] dTitle[i];
}
delete[] dTitle;


for(int i=0; i<arrFoundSize; i++)
{
delete[] m_labels[i];
}
delete[] m_labels;
}

  Re: [MFC]FLICKERING.
Posted by Peter Kwan on Jul-18-2013 04:02
Hi Kaiden,

As you have confirmed, the sample code does not flicker, so the charting code itself should not cause the flickering.

Instead, it is caused by the when and how MFC updates the display, which is related to which type of MFC Window class you are using, how is the Window created and configured, how the controls are laid out, the type of other controls used, etc.. Double-buffering should be one of the methods that may work to solve MFC updating issues.

If you have not yet tried double-buffering, may be you can try it to see if this can solve the problem. If you would need me to help, is it possible to provide a sample code that I can compile and run and that can illustrate the problem? To diagnose the problem, I would need to know how your MFC Window is configured.

Regards
Peter Kwan