|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include "DrawOperator/Xy.h"
|
|
|
|
|
|
#include "DrawOperator/one.h"
|
|
|
|
|
|
#include "Util.h"
|
|
|
|
|
|
|
|
|
|
|
|
class CTextBuilder {
|
|
|
|
|
|
public:
|
|
|
|
|
|
CTextBuilder& FontLocation(double x, double y)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_x = x;
|
|
|
|
|
|
m_y = y;
|
|
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CTextBuilder& FontSize(double width, double height)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_width = width;
|
|
|
|
|
|
m_height = height;
|
|
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CTextBuilder& Text(const CString& text)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_text = text;
|
|
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CText> Build() const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CText> pText = std::make_unique<CText>();
|
|
|
|
|
|
|
|
|
|
|
|
const CString formatStr = "%lf,%lf,0.00000000 98\n"
|
|
|
|
|
|
"{\n"
|
|
|
|
|
|
"%s\n"
|
|
|
|
|
|
"}\n"
|
|
|
|
|
|
"%lf %lf 0.000000 0 400 0 0 0 1 0 16 0 0 Times New Roman";
|
|
|
|
|
|
|
|
|
|
|
|
CString content;
|
|
|
|
|
|
content.Format(formatStr, m_x, m_y, m_text, m_width, m_height);
|
|
|
|
|
|
|
|
|
|
|
|
CMemFile memFile((BYTE*)content.GetString(), content.GetLength());
|
|
|
|
|
|
pText->Read(memFile, CUR_VERSION);
|
|
|
|
|
|
|
|
|
|
|
|
return pText;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
double m_x = 0.0;
|
|
|
|
|
|
double m_y = 0.0;
|
|
|
|
|
|
double m_width = 21.0;
|
|
|
|
|
|
double m_height = 52.0;
|
|
|
|
|
|
CString m_text;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ͼ<EFBFBD><EFBFBD> Item
|
|
|
|
|
|
*/
|
|
|
|
|
|
class LegendItem
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
LegendItem(CXy& xy, CLayer* pLayer)
|
|
|
|
|
|
: m_sourceXy(xy), m_pLayer(pLayer)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(m_pLayer != nullptr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
const CString GetName() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return Path::GetFileNameWithoutExtension(m_pLayer->GetName());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ռ<EFBFBD>÷<EFBFBD>Χ
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param x <EFBFBD><EFBFBD><EFBFBD>½<EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param y <EFBFBD><EFBFBD><EFBFBD>½<EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param width <EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param height <EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void SetBounds(double x, double y, double width, double height)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_x = x;
|
|
|
|
|
|
m_y = y;
|
|
|
|
|
|
m_width = width;
|
|
|
|
|
|
m_height = height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD>ռ<EFBFBD>÷<EFBFBD>Χ
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param x <EFBFBD><EFBFBD><EFBFBD>½<EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param y <EFBFBD><EFBFBD><EFBFBD>½<EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param width <EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param height <EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void GetBounds(double& x, double& y, double& width, double& height) const
|
|
|
|
|
|
{
|
|
|
|
|
|
x = m_x;
|
|
|
|
|
|
y = m_y;
|
|
|
|
|
|
width = m_width;
|
|
|
|
|
|
height = m_height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy Ҫ<EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD> xy
|
|
|
|
|
|
*/
|
|
|
|
|
|
void Build(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildCurveRange(targetXy);
|
|
|
|
|
|
BuildElement(targetXy);
|
|
|
|
|
|
BuildName(targetXy);
|
|
|
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy Ҫ<EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void BuildName(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
CString name = GetName();
|
|
|
|
|
|
auto [x, y] = MeasureNameLocation(name);
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CText> pText = CTextBuilder()
|
|
|
|
|
|
.FontLocation(x, y)
|
|
|
|
|
|
.FontSize(10, 26)
|
|
|
|
|
|
.Text(name)
|
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
|
|
CLayer* pLayer = targetXy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<COne> pOne = std::make_unique<COne>();
|
|
|
|
|
|
pOne->SetLayer(pLayer);
|
|
|
|
|
|
pOne->SetValueSafe(pText.release());
|
|
|
|
|
|
pOne->SetColor(RGB(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
|
|
targetXy.AddTailOne(pOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>ص㣬<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߾ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD> COne ָ<EFBFBD>룬ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> nullptr
|
|
|
|
|
|
*/
|
|
|
|
|
|
COne* GetFirstPointOrCurve() const
|
|
|
|
|
|
{
|
|
|
|
|
|
CPositionList select;
|
|
|
|
|
|
m_sourceXy.GetElement(m_pLayer, select);
|
|
|
|
|
|
|
|
|
|
|
|
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
|
|
|
|
|
|
{
|
|
|
|
|
|
POSITION pt = select.GetAt(pos);
|
|
|
|
|
|
COne* pOne = m_sourceXy.GetAt(pt);
|
|
|
|
|
|
|
|
|
|
|
|
if (pOne->GetType() == DOUBLEFOX_POINT || pOne->GetType() == DOUBLEFOX_CURVE)
|
|
|
|
|
|
{
|
|
|
|
|
|
return pOne;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy
|
|
|
|
|
|
*/
|
|
|
|
|
|
void BuildElement(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
COne* pOne = GetFirstPointOrCurve();
|
|
|
|
|
|
if (pOne == nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<COne> pNewOne = std::make_unique<COne>();
|
|
|
|
|
|
*pNewOne = *pOne;
|
|
|
|
|
|
|
|
|
|
|
|
CRect8 oldRange;
|
|
|
|
|
|
oldRange.SetRect(1e100, -1e100, -1e100, 1e100);
|
|
|
|
|
|
pOne->GetRange(oldRange);
|
|
|
|
|
|
|
|
|
|
|
|
if (pOne->GetType() == DOUBLEFOX_POINT) // <20><><EFBFBD><EFBFBD><EFBFBD>ǵ㣬<C7B5><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
{
|
|
|
|
|
|
CPointNameEx* pPoint = pNewOne->GetValueSafe<CPointNameEx>();
|
|
|
|
|
|
assert(pPoint != nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
CenterPointInRange(*pPoint, CanvasRect());
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pOne->GetType() == DOUBLEFOX_CURVE) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
{
|
|
|
|
|
|
CCurveEx* pCurve = pNewOne->GetValueSafe<CCurveEx>();
|
|
|
|
|
|
assert(pCurve != nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
CenterCurveInRange(*pCurve, CanvasRect());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CLayer* pLayer = targetXy.FindAddLayer(m_pLayer->GetPathName());
|
|
|
|
|
|
CopyLayerHowtoViewTo(m_pLayer, pLayer);
|
|
|
|
|
|
pNewOne->SetLayer(pLayer);
|
|
|
|
|
|
pNewOne->SetColor(RGB(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
|
|
targetXy.AddTailOne(pNewOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param point
|
|
|
|
|
|
* \param range
|
|
|
|
|
|
*/
|
|
|
|
|
|
void CenterPointInRange(CPointNameEx& point, const CRect8& range) const
|
|
|
|
|
|
{
|
|
|
|
|
|
point.x0 = range.left + (range.right - range.left) / 2;
|
|
|
|
|
|
point.y0 = range.bottom + (range.top - range.bottom) / 2;
|
|
|
|
|
|
point.SetName(""); // <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߷ŵ<EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param curve
|
|
|
|
|
|
* \param range
|
|
|
|
|
|
*/
|
|
|
|
|
|
void CenterCurveInRange(CCurveEx& curve, const CRect8& range) const
|
|
|
|
|
|
{
|
|
|
|
|
|
CRect8 oldRange;
|
|
|
|
|
|
oldRange.SetRect(1e100, -1e100, -1e100, 1e100);
|
|
|
|
|
|
curve.GetRange(oldRange);
|
|
|
|
|
|
|
|
|
|
|
|
CRect8 newRange = ScaleRect(range, 0.9);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < curve.num; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto [x, y] = ScalePoint(curve.x[i], curve.y[i], oldRange, newRange);
|
|
|
|
|
|
curve.x[i] = x;
|
|
|
|
|
|
curve.y[i] = y;
|
|
|
|
|
|
}
|
|
|
|
|
|
curve.GetLocation();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy
|
|
|
|
|
|
*/
|
|
|
|
|
|
void BuildCurveRange(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CCurveEx> pCurve = std::make_unique<CCurveEx>();
|
|
|
|
|
|
pCurve->Create(5);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double y = m_y + m_height * (1 - m_canvasHeightRatio);
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[0] = m_x;
|
|
|
|
|
|
pCurve->y[0] = y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[1] = m_x + m_width;
|
|
|
|
|
|
pCurve->y[1] = y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[2] = m_x + m_width;
|
|
|
|
|
|
pCurve->y[2] = m_y + m_height;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[3] = m_x;
|
|
|
|
|
|
pCurve->y[3] = m_y + m_height;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[4] = m_x;
|
|
|
|
|
|
pCurve->y[4] = y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->GetLocation();
|
|
|
|
|
|
|
|
|
|
|
|
CLayer* pLayer = targetXy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<COne> pOne = std::make_unique<COne>();
|
|
|
|
|
|
pOne->SetValueSafe(pCurve.release());
|
|
|
|
|
|
pOne->SetLayer(pLayer);
|
|
|
|
|
|
pOne->SetColor(RGB(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
|
|
targetXy.AddTailOne(pOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>η<EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>η<EFBFBD>Χ
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param x x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param y y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param oldRange <EFBFBD>ɵķ<EFBFBD>Χ
|
|
|
|
|
|
* \param newRange <EFBFBD>µķ<EFBFBD>Χ
|
|
|
|
|
|
* \return <EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><EFBFBD><EFBFBD> x y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::pair<double, double> ScalePoint(double x, double y, const CRect8& oldRange, const CRect8& newRange) const
|
|
|
|
|
|
{
|
|
|
|
|
|
double xMin = oldRange.left;
|
|
|
|
|
|
double xMax = oldRange.right;
|
|
|
|
|
|
double yMin = oldRange.bottom;
|
|
|
|
|
|
double yMax = oldRange.top;
|
|
|
|
|
|
|
|
|
|
|
|
double newXMin = newRange.left;
|
|
|
|
|
|
double newXMax = newRange.right;
|
|
|
|
|
|
double newYMin = newRange.bottom;
|
|
|
|
|
|
double newYMax = newRange.top;
|
|
|
|
|
|
|
|
|
|
|
|
double newX = ((x - xMin) / (xMax - xMin)) * (newXMax - newXMin) + newXMin;
|
|
|
|
|
|
double newY = ((y - yMin) / (yMax - yMin)) * (newYMax - newYMin) + newYMin;
|
|
|
|
|
|
|
|
|
|
|
|
return { newX, newY };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
CRect8 CanvasRect() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return CRect8(m_x, m_y + m_height, m_x + m_width, m_y + m_height * (1 - m_canvasHeightRatio));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param rect Ҫ<EFBFBD><EFBFBD><EFBFBD>ŵľ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param scaleFactor <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
CRect8 ScaleRect(const CRect8& rect, double scaleFactor) const
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(scaleFactor > 0);
|
|
|
|
|
|
|
|
|
|
|
|
double width = rect.right - rect.left;
|
|
|
|
|
|
double height = rect.top - rect.bottom;
|
|
|
|
|
|
|
|
|
|
|
|
double newWidth = width * scaleFactor;
|
|
|
|
|
|
double newHeight = height * scaleFactor;
|
|
|
|
|
|
|
|
|
|
|
|
double left = rect.left + (width - newWidth) / 2;
|
|
|
|
|
|
double top = rect.top - (height - newHeight) / 2;
|
|
|
|
|
|
double right = rect.right - (width - newWidth) / 2;
|
|
|
|
|
|
double bottom = rect.bottom + (height - newHeight) / 2;
|
|
|
|
|
|
return CRect8(left, top, right, bottom);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD> x, y λ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param text
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::pair<double, double> MeasureNameLocation(const CString& name) const
|
|
|
|
|
|
{
|
|
|
|
|
|
double x = m_x + m_width / 2; // Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵĿ<D6B5><C4BF>ȼ<EFBFBD><C8BC><EFBFBD> x <20><>λ<EFBFBD>ã<EFBFBD>Ŀǰ<C4BF><C7B0> x <20><><EFBFBD>õ<EFBFBD><C3B5>м<EFBFBD>λ<EFBFBD>ã<EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>м<EFBFBD>
|
|
|
|
|
|
double height = m_height * (1 - m_canvasHeightRatio); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
|
|
|
|
|
|
double y = m_y + height; // y ̧<><CCA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>
|
|
|
|
|
|
y -= height * m_nameOffsetRatio; // <20><><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾλ<CABE><CEBB>
|
|
|
|
|
|
return { x, y };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵѿ<C7B5><D1BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x y <20><><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵһ<D2B5><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double m_x = 0.0; // <20><><EFBFBD><EFBFBD> x
|
|
|
|
|
|
double m_y = 0.0; // <20><><EFBFBD><EFBFBD> y
|
|
|
|
|
|
double m_width = 2.0; // <20><><EFBFBD><EFBFBD>
|
|
|
|
|
|
double m_height = 1.0; // <20>߶<EFBFBD>
|
|
|
|
|
|
double m_nameOffsetRatio = 7.0 / 52.0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾλ<CABE>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƹ߶<C6B8>ռ<EFBFBD><D5BC>
|
|
|
|
|
|
double m_canvasHeightRatio = 65.0 / 117.0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶Ⱥ<DFB6><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶ȵı<C8B5><C4B1><EFBFBD>
|
|
|
|
|
|
CXy& m_sourceXy; // ԭͼ<D4AD><CDBC>xy<78><79><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ɷ<EFBFBD><C9B7>ŵ<EFBFBD>ͼ<EFBFBD><CDBC> xy
|
|
|
|
|
|
CLayer* m_pLayer = nullptr; // Ҫ<><D2AA><EFBFBD>ɷ<EFBFBD><C9B7>ŵ<EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
class Legend
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>캯<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param title <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param columns <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param layers <EFBFBD><EFBFBD>Щͼ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
Legend(CXy &xy, double x, double y, double width, const CString& title, int columns, const std::vector<CString>& layers = {})
|
|
|
|
|
|
: m_sourceXy(xy), m_x(x), m_y(y), m_width(width), m_title(title), m_columns(columns), m_layers(layers)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (const CString& layer : layers)
|
|
|
|
|
|
{
|
|
|
|
|
|
CLayer* pLayer = m_sourceXy.FindLayer(layer);
|
|
|
|
|
|
if (pLayer != nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_boxes.emplace_back(m_sourceXy, pLayer);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \return <EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ͼ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::unique_ptr<CInsertBlock> Build()
|
|
|
|
|
|
{
|
|
|
|
|
|
ComputeLayout();
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CXy> pNewXy = std::make_unique<CXy>();
|
|
|
|
|
|
pNewXy->color = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>߿<EFBFBD>
|
|
|
|
|
|
BuildCurveRange(*pNewXy);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
BuildTitle(*pNewXy);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC> item
|
|
|
|
|
|
for (auto& box : m_boxes)
|
|
|
|
|
|
{
|
|
|
|
|
|
box.Build(*pNewXy);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD> Block
|
|
|
|
|
|
std::unique_ptr<CInsertBlock> pBlock = std::make_unique<CInsertBlock>();
|
|
|
|
|
|
pBlock->SetXy(pNewXy.release());
|
|
|
|
|
|
|
|
|
|
|
|
return pBlock;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ռ<EFBFBD>Ŀռ<EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
void ComputeLayout()
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t rows = m_boxes.size() / m_columns + (m_boxes.size() % m_columns == 0 ? 0 : 1);
|
|
|
|
|
|
size_t columns = m_columns;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>϶<EFBFBD><CFB6><EFBFBD><EFBFBD>
|
|
|
|
|
|
double horizontalSpacing = CalcHorizontalSpacing(m_width, static_cast<int>(columns), m_boxWidthSpacingRatio);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>
|
|
|
|
|
|
m_boxWidth = horizontalSpacing * m_boxWidthSpacingRatio;
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ĸ߶ȣ<DFB6><C8A3><EFBFBD><EFBFBD>ƿ<EFBFBD><C6BF>߱<EFBFBD>Ϊ 10 <20><> 8
|
|
|
|
|
|
m_boxHeight = m_boxWidth * m_widthHeightRatio;
|
|
|
|
|
|
|
|
|
|
|
|
m_titleHeight = m_boxWidth * m_titleWidthRatio;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>߶<EFBFBD>
|
|
|
|
|
|
m_height = m_boxHeight * rows + m_titleHeight;
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < m_boxes.size(); i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t row = i / columns;
|
|
|
|
|
|
size_t column = i % columns;
|
|
|
|
|
|
|
|
|
|
|
|
// x ƫ<><C6AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><D0BF><EFBFBD><EFBFBD>м<EFBFBD>϶<EFBFBD><CFB6><EFBFBD><EFBFBD>
|
|
|
|
|
|
double xOffset = column * m_boxWidth + (column + 1) * horizontalSpacing;
|
|
|
|
|
|
double yOffset = (row + 1) * m_boxHeight;
|
|
|
|
|
|
|
|
|
|
|
|
// y <20><><EFBFBD>鷳<EFBFBD>Ķ<EFBFBD>
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>λ<EFBFBD><CEBB>
|
|
|
|
|
|
// Ȼ<><C8BB><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½ǵ<C2BD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>Ի<EFBFBD>Ҫ<EFBFBD>ټ<EFBFBD><D9BC><EFBFBD> boxHeight
|
|
|
|
|
|
yOffset = m_height - yOffset - m_titleHeight;
|
|
|
|
|
|
|
|
|
|
|
|
m_boxes[i].SetBounds(xOffset, yOffset, m_boxWidth, m_boxHeight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OffsetBoxes();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetWidth() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_width;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double GetHeight() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_height;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ǰ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD><EFBFBD> 0,0 Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꿪ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> m_x, m_y <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
void OffsetBoxes()
|
|
|
|
|
|
{
|
|
|
|
|
|
for (auto& box : m_boxes)
|
|
|
|
|
|
{
|
|
|
|
|
|
double x = 0.0;
|
|
|
|
|
|
double y = 0.0;
|
|
|
|
|
|
double width = 0.0;
|
|
|
|
|
|
double height = 0.0;
|
|
|
|
|
|
box.GetBounds(x, y, width, height);
|
|
|
|
|
|
box.SetBounds(m_x + x, m_y + y, width, height);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ѿ<EFBFBD><D1BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
|
|
|
|
|
|
std::tuple<double, double, double, double> ScaleRect(double x, double y, double width, double height, double scaleFactor)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(scaleFactor > 0 && scaleFactor <= 1);
|
|
|
|
|
|
|
|
|
|
|
|
double newWidth = width * scaleFactor;
|
|
|
|
|
|
double newHeight = width * scaleFactor;
|
|
|
|
|
|
|
|
|
|
|
|
double newX = x + ((width - newWidth) / 2);
|
|
|
|
|
|
double newY = y + ((height - newHeight) / 2);
|
|
|
|
|
|
|
|
|
|
|
|
return { newX, newY, newWidth, newHeight };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy Ҫ<EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void BuildCurveRange(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CCurveEx> pCurve = std::make_unique<CCurveEx>();
|
|
|
|
|
|
pCurve->Create(5);
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[0] = m_x;
|
|
|
|
|
|
pCurve->y[0] = m_y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[1] = m_x + m_width;
|
|
|
|
|
|
pCurve->y[1] = m_y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[2] = m_x + m_width;
|
|
|
|
|
|
pCurve->y[2] = m_y + m_height;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[3] = m_x;
|
|
|
|
|
|
pCurve->y[3] = m_y + m_height;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->x[4] = m_x;
|
|
|
|
|
|
pCurve->y[4] = m_y;
|
|
|
|
|
|
|
|
|
|
|
|
pCurve->GetLocation();
|
|
|
|
|
|
|
|
|
|
|
|
CLayer* pLayer = targetXy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<COne> pOne = std::make_unique<COne>();
|
|
|
|
|
|
pOne->SetValueSafe(pCurve.release());
|
|
|
|
|
|
pOne->SetLayer(pLayer);
|
|
|
|
|
|
pOne->HowToViewCurve = CreateBorderHowToView().release();
|
|
|
|
|
|
|
|
|
|
|
|
targetXy.AddTailOne(pOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param targetXy Ҫ<EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void BuildTitle(CXy& targetXy) const
|
|
|
|
|
|
{
|
|
|
|
|
|
double x = m_x + m_width * 0.5;
|
|
|
|
|
|
double y = m_y + m_height - m_titleHeight * m_titleOffsetRatio;
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CText> pText = CTextBuilder()
|
|
|
|
|
|
.FontLocation(x, y)
|
|
|
|
|
|
.FontSize(21, 52)
|
|
|
|
|
|
.Text("ͼ <20><>")
|
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
|
|
CLayer* pLayer = targetXy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<COne> pOne = std::make_unique<COne>();
|
|
|
|
|
|
pOne->SetLayer(pLayer);
|
|
|
|
|
|
pOne->SetValueSafe(pText.release());
|
|
|
|
|
|
pOne->SetColor(RGB(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
|
|
targetXy.AddTailOne(pOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ӿ鵽ԭͼ<EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param pBlock <EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
void AddBlock(std::unique_ptr<CInsertBlock> pBlock)
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<COne> pOne = std::make_unique<COne>();
|
|
|
|
|
|
CLayer *pLayer = m_sourceXy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
|
|
|
|
|
|
pOne->SetValueSafe(pBlock.release());
|
|
|
|
|
|
pOne->SetLayer(pLayer);
|
|
|
|
|
|
m_sourceXy.AddTailOne(pOne.release());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>߿<EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::unique_ptr<CHowToViewCurve> CreateBorderHowToView() const
|
|
|
|
|
|
{
|
|
|
|
|
|
std::unique_ptr<CCurvePropertiesEx> prop1 = std::make_unique<CCurvePropertiesEx>();
|
|
|
|
|
|
prop1->m_size = 0;
|
|
|
|
|
|
prop1->color = abs(16777215);
|
|
|
|
|
|
prop1->m_nFlags = 65568;
|
|
|
|
|
|
prop1->m_SmoothStep = 0;
|
|
|
|
|
|
prop1->m_offset = 0;
|
|
|
|
|
|
prop1->m_stuCurveWave.T = 0;
|
|
|
|
|
|
prop1->m_stuCurveWave.T = 0;
|
|
|
|
|
|
prop1->m_stuCurveWave.A = 0;
|
|
|
|
|
|
prop1->m_stuCurveWave.dnum = 0;
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CCurvePropertiesEx> prop2 = std::make_unique<CCurvePropertiesEx>();
|
|
|
|
|
|
prop2->m_size = 0;
|
|
|
|
|
|
prop2->color = abs(0);
|
|
|
|
|
|
prop2->m_nFlags = 65536;
|
|
|
|
|
|
prop2->m_SmoothStep = 0;
|
|
|
|
|
|
prop2->m_offset = 0;
|
|
|
|
|
|
prop2->m_stuCurveWave.T = 0;
|
|
|
|
|
|
prop2->m_stuCurveWave.T = 0;
|
|
|
|
|
|
prop2->m_stuCurveWave.A = 0;
|
|
|
|
|
|
prop2->m_stuCurveWave.dnum = 0;
|
|
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<CHowToViewCurve> pHowToViewCurve = std::make_unique<CHowToViewCurve>();
|
|
|
|
|
|
pHowToViewCurve->Add(prop1.release());
|
|
|
|
|
|
pHowToViewCurve->Add(prop2.release());
|
|
|
|
|
|
|
|
|
|
|
|
return pHowToViewCurve;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>ܿ<EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><EFBFBD>ͼ<EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* \param width <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param n <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \param ratio <EFBFBD>кͼ<EFBFBD>϶<EFBFBD>Ŀ<EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* \return
|
|
|
|
|
|
*/
|
|
|
|
|
|
double CalcHorizontalSpacing(double width, int n, double ratio) const
|
|
|
|
|
|
{
|
|
|
|
|
|
// <20>ܹ<EFBFBD> n <20>У<EFBFBD><D0A3><EFBFBD>϶Ϊ n + 1 <20><>
|
|
|
|
|
|
// (n + 1) * space + n * boxWidth = width
|
|
|
|
|
|
// boxWidth = ratio * space
|
|
|
|
|
|
// (n + 1) * space + n * (ratio * space) = width
|
|
|
|
|
|
// (n + 1 + n * ratio) * space = width
|
|
|
|
|
|
// space = width / (n + 1 + n * ratio)
|
|
|
|
|
|
|
|
|
|
|
|
return width / (n + 1 + n * ratio);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵѿ<C7B5><D1BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x y <20><><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵһ<D2B5><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
double m_x = 0.0;
|
|
|
|
|
|
double m_y = 0.0;
|
|
|
|
|
|
double m_width = 512.0;
|
|
|
|
|
|
double m_height = 421.0;
|
|
|
|
|
|
CString m_title;
|
|
|
|
|
|
// ÿ<>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC> Item <20><><EFBFBD><EFBFBD>Ϊ 46 <20><> 106
|
|
|
|
|
|
double m_boxWidthSpacingRatio = 106.0 / 46.0;
|
|
|
|
|
|
// ͼ<>п<EFBFBD><D0BF>߱<EFBFBD>
|
|
|
|
|
|
double m_widthHeightRatio = 106.0 / 117.0;
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ȵı<C8B5><C4B1><EFBFBD>
|
|
|
|
|
|
double m_titleWidthRatio = 77.0 / 106.0;
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼλ<CABC><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>ռ<EFBFBD><D5BC>
|
|
|
|
|
|
double m_titleOffsetRatio = 10.0 / 77.0;
|
|
|
|
|
|
double m_boxWidth = 0.0;
|
|
|
|
|
|
double m_boxHeight = 0.0;
|
|
|
|
|
|
double m_titleHeight = 0.0;
|
|
|
|
|
|
int m_columns = 3;
|
|
|
|
|
|
std::vector<CString> m_layers;
|
|
|
|
|
|
std::vector<LegendItem> m_boxes;
|
|
|
|
|
|
CXy& m_sourceXy;
|
|
|
|
|
|
};
|