column chart with logarithmic scaling

D

Dirk

Hello

I have a ColumnClustered chart with a logarithmic scaling for the value axis
(left) with a fixed minimum of 0.1. Now the columns do not start at the
bottom (0.1) but instead at 1. All values are >= 1. If there are values < 1
these columns go down from 1 towards 0.1. All I want is a simple column
chart where the columns start at the specified minimum. I tried various
settings for CrossingAxis, CrossesAtValue but only could move the labels.
With a normal Excel chart I just have to set "Category (X) axis crosses at"
to 0.1 and get what I want.
Is this not possible with the web components chart.

Thanks
 
A

Alvin Bruney [ASP.NET MVP]

Have you tried setting the minValue for the specified axis? That should
work.

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
 
D

Dirk

Alvin Bruney said:
Have you tried setting the minValue for the specified axis? That should
work.

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------
Hello Alvin

Perhaps I was a bit unclear. I have specified a minimum of 0.1 and the
values axis really starts there, but the bars are not drawn below value 1.
This is the case for all values >= 1.0 (I have attached a picture of this
scenario). If the values are < 1 they are drawn from the value 1 down to
their real value. Further below is the code that creates the chart. The code
uses version 9 of msowc.dll and the chart is hosted on a dialog of an Excel
COM add-in. I use this modal dialog during some data aquisition from an
external measurement device. The add-in has event handlers to get the data
and then puts it into a prepared worksheet. The PutValue call will fail if
the user currently edits a cell (perhaps in another workbook) or
double-clicks one of the sheet tabs and Excel would display a dialog saying
the workbook is protected. During this time Excel will not allow PutValue
calls for the Range object and the data would be lost. The only reliable way
I have found is to display a modal dialog during the measurement procedure
that disallows any other interaction with Excel.
Therefore I looked at the web components to get a chart on my dialog.
Actually I was very pleased to find out that owc version allows maximum
values on a log scale axis that are not integer powers of 10, e.g. 300.
This cannot be achieved with normal excel charts.
The only problem I see with owc relates to compatibility. I have seen a lot
of posts about this. My add-in is supposed to work with excel 2000 and later
versions, so I #import the excel 2000 typelib in my ATL project. But I am
really not sure about owc. All I know is that the user will have excel
installed. Is OWC always installed or can the user unselect it during setup?
And what typelib should I use so that regardless of the excel version my
code always works?

void MeasInfoDlg::CreateChart()
{
try
{
chart_.Attach(GetDlgItem(IDC_CHART2));
IUnknownPtr pIUnk;
HRESULT hr = chart_.QueryControl(&pIUnk);
ATLASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
OWC::WCWebChartPtr webChart = pIUnk;
webChart->AllowAboutDialog = VARIANT_FALSE;

OWC::WCChartPtr ch = webChart->Charts->Add(-1);
ch->Type = OWC::chChartTypeColumnClustered;

// set up values axis
OWC::WCAxisPtr yAxis = ch->Axes->Item[0];
yAxis->HasTitle = VARIANT_TRUE;
yAxis->Title->Caption = L"Values";
yAxis->Scaling->Type = OWC::chScaleTypeLogarithmic;
yAxis->Scaling->Minimum = 0.1;

// set up category axis
OWC::WCAxisPtr xAxis = ch->Axes->Item[1];
xAxis->HasTitle = VARIANT_TRUE;
xAxis->Title->Caption = L"Categories";

yAxis->CrossingAxis = xAxis;
xAxis->CrossesAtValue = 0.1;

CComSafeArray<VARIANT> arrCat(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrCat = 1 + i;
}

CComSafeArray<VARIANT> arrVal(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrVal = 10 * (CHANNEL_COUNT - i + 1);
}

_variant_t varCat;
varCat.parray = arrCat.Detach();
varCat.vt = VT_ARRAY | VT_VARIANT;
ch->SetData(OWC::chDimCategories, OWC::chDataLiteral, varCat);

_variant_t varVal;
varVal.parray = arrVal.Detach();
varVal.vt = VT_ARRAY | VT_VARIANT;
OWC::WCSeriesPtr series = ch->SeriesCollection->Add(-1);
series->SetData(OWC::chDimValues, OWC::chDataLiteral, varVal);

webChart->ExportPicture(L"c:\\chart01.gif", L"GIF", -1, -1);
}

}
catch(const _com_error &e)
{
_bstr_t desc = e.Description();
ATLTRACE2(atlTraceGeneral, 0, _T("%s : %X\n"), (!desc) ? _T("-") :
(LPCTSTR)desc, e.Error);
}
}
 
A

Alvin Bruney [ASP.NET MVP]

yuck! this is C++ code. could'a warned me.

Give me sometime to dust off my C++ compiler. I'll get back to you sometime
this week (if no body else volunteers to take this cup of suffering from
me).

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------

Dirk said:
Alvin Bruney said:
Have you tried setting the minValue for the specified axis? That should
work.

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------
Hello Alvin

Perhaps I was a bit unclear. I have specified a minimum of 0.1 and the
values axis really starts there, but the bars are not drawn below value 1.
This is the case for all values >= 1.0 (I have attached a picture of this
scenario). If the values are < 1 they are drawn from the value 1 down to
their real value. Further below is the code that creates the chart. The
code uses version 9 of msowc.dll and the chart is hosted on a dialog of an
Excel COM add-in. I use this modal dialog during some data aquisition from
an external measurement device. The add-in has event handlers to get the
data and then puts it into a prepared worksheet. The PutValue call will
fail if the user currently edits a cell (perhaps in another workbook) or
double-clicks one of the sheet tabs and Excel would display a dialog
saying the workbook is protected. During this time Excel will not allow
PutValue calls for the Range object and the data would be lost. The only
reliable way I have found is to display a modal dialog during the
measurement procedure that disallows any other interaction with Excel.
Therefore I looked at the web components to get a chart on my dialog.
Actually I was very pleased to find out that owc version allows maximum
values on a log scale axis that are not integer powers of 10, e.g. 300.
This cannot be achieved with normal excel charts.
The only problem I see with owc relates to compatibility. I have seen a
lot of posts about this. My add-in is supposed to work with excel 2000 and
later versions, so I #import the excel 2000 typelib in my ATL project. But
I am really not sure about owc. All I know is that the user will have
excel installed. Is OWC always installed or can the user unselect it
during setup? And what typelib should I use so that regardless of the
excel version my code always works?

void MeasInfoDlg::CreateChart()
{
try
{
chart_.Attach(GetDlgItem(IDC_CHART2));
IUnknownPtr pIUnk;
HRESULT hr = chart_.QueryControl(&pIUnk);
ATLASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
OWC::WCWebChartPtr webChart = pIUnk;
webChart->AllowAboutDialog = VARIANT_FALSE;

OWC::WCChartPtr ch = webChart->Charts->Add(-1);
ch->Type = OWC::chChartTypeColumnClustered;

// set up values axis
OWC::WCAxisPtr yAxis = ch->Axes->Item[0];
yAxis->HasTitle = VARIANT_TRUE;
yAxis->Title->Caption = L"Values";
yAxis->Scaling->Type = OWC::chScaleTypeLogarithmic;
yAxis->Scaling->Minimum = 0.1;

// set up category axis
OWC::WCAxisPtr xAxis = ch->Axes->Item[1];
xAxis->HasTitle = VARIANT_TRUE;
xAxis->Title->Caption = L"Categories";

yAxis->CrossingAxis = xAxis;
xAxis->CrossesAtValue = 0.1;

CComSafeArray<VARIANT> arrCat(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrCat = 1 + i;
}

CComSafeArray<VARIANT> arrVal(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrVal = 10 * (CHANNEL_COUNT - i + 1);
}

_variant_t varCat;
varCat.parray = arrCat.Detach();
varCat.vt = VT_ARRAY | VT_VARIANT;
ch->SetData(OWC::chDimCategories, OWC::chDataLiteral, varCat);

_variant_t varVal;
varVal.parray = arrVal.Detach();
varVal.vt = VT_ARRAY | VT_VARIANT;
OWC::WCSeriesPtr series = ch->SeriesCollection->Add(-1);
series->SetData(OWC::chDimValues, OWC::chDataLiteral, varVal);

webChart->ExportPicture(L"c:\\chart01.gif", L"GIF", -1, -1);
}

}
catch(const _com_error &e)
{
_bstr_t desc = e.Description();
ATLTRACE2(atlTraceGeneral, 0, _T("%s : %X\n"), (!desc) ? _T("-") :
(LPCTSTR)desc, e.Error);
}
}
 
D

Dirk

A working VB/C# example will suffice. By the way I tried it also with owc11
and the behaviour is the same.

Thanks,
Dirk


Alvin Bruney said:
yuck! this is C++ code. could'a warned me.

Give me sometime to dust off my C++ compiler. I'll get back to you
sometime this week (if no body else volunteers to take this cup of
suffering from me).

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------

Dirk said:
Alvin Bruney said:
Have you tried setting the minValue for the specified axis? That should
work.

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------
Hello Alvin

Perhaps I was a bit unclear. I have specified a minimum of 0.1 and the
values axis really starts there, but the bars are not drawn below value
1. This is the case for all values >= 1.0 (I have attached a picture of
this scenario). If the values are < 1 they are drawn from the value 1
down to their real value. Further below is the code that creates the
chart. The code uses version 9 of msowc.dll and the chart is hosted on a
dialog of an Excel COM add-in. I use this modal dialog during some data
aquisition from an external measurement device. The add-in has event
handlers to get the data and then puts it into a prepared worksheet. The
PutValue call will fail if the user currently edits a cell (perhaps in
another workbook) or double-clicks one of the sheet tabs and Excel would
display a dialog saying the workbook is protected. During this time Excel
will not allow PutValue calls for the Range object and the data would be
lost. The only reliable way I have found is to display a modal dialog
during the measurement procedure that disallows any other interaction
with Excel.
Therefore I looked at the web components to get a chart on my dialog.
Actually I was very pleased to find out that owc version allows maximum
values on a log scale axis that are not integer powers of 10, e.g. 300.
This cannot be achieved with normal excel charts.
The only problem I see with owc relates to compatibility. I have seen a
lot of posts about this. My add-in is supposed to work with excel 2000
and later versions, so I #import the excel 2000 typelib in my ATL
project. But I am really not sure about owc. All I know is that the user
will have excel installed. Is OWC always installed or can the user
unselect it during setup? And what typelib should I use so that
regardless of the excel version my code always works?

void MeasInfoDlg::CreateChart()
{
try
{
chart_.Attach(GetDlgItem(IDC_CHART2));
IUnknownPtr pIUnk;
HRESULT hr = chart_.QueryControl(&pIUnk);
ATLASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
OWC::WCWebChartPtr webChart = pIUnk;
webChart->AllowAboutDialog = VARIANT_FALSE;

OWC::WCChartPtr ch = webChart->Charts->Add(-1);
ch->Type = OWC::chChartTypeColumnClustered;

// set up values axis
OWC::WCAxisPtr yAxis = ch->Axes->Item[0];
yAxis->HasTitle = VARIANT_TRUE;
yAxis->Title->Caption = L"Values";
yAxis->Scaling->Type = OWC::chScaleTypeLogarithmic;
yAxis->Scaling->Minimum = 0.1;

// set up category axis
OWC::WCAxisPtr xAxis = ch->Axes->Item[1];
xAxis->HasTitle = VARIANT_TRUE;
xAxis->Title->Caption = L"Categories";

yAxis->CrossingAxis = xAxis;
xAxis->CrossesAtValue = 0.1;

CComSafeArray<VARIANT> arrCat(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrCat = 1 + i;
}

CComSafeArray<VARIANT> arrVal(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrVal = 10 * (CHANNEL_COUNT - i + 1);
}

_variant_t varCat;
varCat.parray = arrCat.Detach();
varCat.vt = VT_ARRAY | VT_VARIANT;
ch->SetData(OWC::chDimCategories, OWC::chDataLiteral, varCat);

_variant_t varVal;
varVal.parray = arrVal.Detach();
varVal.vt = VT_ARRAY | VT_VARIANT;
OWC::WCSeriesPtr series = ch->SeriesCollection->Add(-1);
series->SetData(OWC::chDimValues, OWC::chDataLiteral, varVal);

webChart->ExportPicture(L"c:\\chart01.gif", L"GIF", -1, -1);
}

}
catch(const _com_error &e)
{
_bstr_t desc = e.Description();
ATLTRACE2(atlTraceGeneral, 0, _T("%s : %X\n"), (!desc) ? _T("-") :
(LPCTSTR)desc, e.Error);
}
}

 
A

Alvin Bruney [ASP.NET MVP]

Sorry for the delay my laptop was down for a couple days.

couple things
- i'm not sure what you benefit you are getting by declaring the chart on
the heap, why isn't it a stack object?

My add-in is supposed to work with excel 2000 and later
versions, so I #import the excel 2000 typelib in my ATL project. But I am
really not sure about owc. All I know is that the user will have excel
installed. Is OWC always installed or can the user unselect it during
setup? And what typelib should I use so that regardless of the excel
version my code always works?

if you are working with office 2000 servicing owc version 9, it is safe to
assume that the owc is installed. if you are targetting office xp which is
the same family of office 2000 products, you will have to write a sniffer
routine to detect whether or not the user has the owc installed. with
versions 10 and 11, owc is standalone so there really is no guarantee that
it will be on the users system.

for the larger issue, it seems that the OWC makes certain assumptions on the
data with respect to the values that it plots. Without knowing these
assumptions, I cannot classify it as a bug. I'd recommend that you submit an
incident report to microsoft product support to find resolution on the
issue. They can crack the OWC chart code open and find the assumptions. Less
tylenol that way...
--
Regards,
Alvin Bruney
[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
_________________________


Dirk said:
Alvin Bruney said:
Have you tried setting the minValue for the specified axis? That should
work.

--
Regards,
Alvin Bruney

[Shameless Author Plug]
The Microsoft Office Web Components Black Book with .NET
available at www.lulu.com/owc
------------------------------------------------------------
Hello Alvin

Perhaps I was a bit unclear. I have specified a minimum of 0.1 and the
values axis really starts there, but the bars are not drawn below value 1.
This is the case for all values >= 1.0 (I have attached a picture of this
scenario). If the values are < 1 they are drawn from the value 1 down to
their real value. Further below is the code that creates the chart. The
code uses version 9 of msowc.dll and the chart is hosted on a dialog of an
Excel COM add-in. I use this modal dialog during some data aquisition from
an external measurement device. The add-in has event handlers to get the
data and then puts it into a prepared worksheet. The PutValue call will
fail if the user currently edits a cell (perhaps in another workbook) or
double-clicks one of the sheet tabs and Excel would display a dialog
saying the workbook is protected. During this time Excel will not allow
PutValue calls for the Range object and the data would be lost. The only
reliable way I have found is to display a modal dialog during the
measurement procedure that disallows any other interaction with Excel.
Therefore I looked at the web components to get a chart on my dialog.
Actually I was very pleased to find out that owc version allows maximum
values on a log scale axis that are not integer powers of 10, e.g. 300.
This cannot be achieved with normal excel charts.
The only problem I see with owc relates to compatibility. I have seen a
lot of posts about this. My add-in is supposed to work with excel 2000 and
later versions, so I #import the excel 2000 typelib in my ATL project. But
I am really not sure about owc. All I know is that the user will have
excel installed. Is OWC always installed or can the user unselect it
during setup? And what typelib should I use so that regardless of the
excel version my code always works?

void MeasInfoDlg::CreateChart()
{
try
{
chart_.Attach(GetDlgItem(IDC_CHART2));
IUnknownPtr pIUnk;
HRESULT hr = chart_.QueryControl(&pIUnk);
ATLASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr))
{
OWC::WCWebChartPtr webChart = pIUnk;
webChart->AllowAboutDialog = VARIANT_FALSE;

OWC::WCChartPtr ch = webChart->Charts->Add(-1);
ch->Type = OWC::chChartTypeColumnClustered;

// set up values axis
OWC::WCAxisPtr yAxis = ch->Axes->Item[0];
yAxis->HasTitle = VARIANT_TRUE;
yAxis->Title->Caption = L"Values";
yAxis->Scaling->Type = OWC::chScaleTypeLogarithmic;
yAxis->Scaling->Minimum = 0.1;

// set up category axis
OWC::WCAxisPtr xAxis = ch->Axes->Item[1];
xAxis->HasTitle = VARIANT_TRUE;
xAxis->Title->Caption = L"Categories";

yAxis->CrossingAxis = xAxis;
xAxis->CrossesAtValue = 0.1;

CComSafeArray<VARIANT> arrCat(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrCat = 1 + i;
}

CComSafeArray<VARIANT> arrVal(CHANNEL_COUNT);
for (int i = 0; i < CHANNEL_COUNT; ++i) {
arrVal = 10 * (CHANNEL_COUNT - i + 1);
}

_variant_t varCat;
varCat.parray = arrCat.Detach();
varCat.vt = VT_ARRAY | VT_VARIANT;
ch->SetData(OWC::chDimCategories, OWC::chDataLiteral, varCat);

_variant_t varVal;
varVal.parray = arrVal.Detach();
varVal.vt = VT_ARRAY | VT_VARIANT;
OWC::WCSeriesPtr series = ch->SeriesCollection->Add(-1);
series->SetData(OWC::chDimValues, OWC::chDataLiteral, varVal);

webChart->ExportPicture(L"c:\\chart01.gif", L"GIF", -1, -1);
}

}
catch(const _com_error &e)
{
_bstr_t desc = e.Description();
ATLTRACE2(atlTraceGeneral, 0, _T("%s : %X\n"), (!desc) ? _T("-") :
(LPCTSTR)desc, e.Error);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top