PDA

View Full Version : [OPEN] [#77] Chart legend problems with large amount of series



MWM2Dev
Aug 22, 2012, 5:45 PM
Hello!

I have an issue with the chartlegends for a linechart we are using the linechart has 20 or so series and the legend runs out of bounds when we turn it on. I looked around in the legend but can't find a way to force it to show a number of colomns or something similar it seems it always uses one column or one line to show all the series in the legend.
Is there a way I can force the legend to use multiple rows and/or columns?

small example code we are using to produce this error:



for (int i = 4; i <= 20; i++)
{
serie = new LineSeries();
serie.SeriesID = "line" + i.ToString();
serie.YField = new[] { "data2" };
serie.XField = new[] { "periode2" };
serie.Axis = Position.Left;
Chart1.Series.Add(serie);
}


and a picture of the problem
4665

Daniil
Aug 22, 2012, 7:01 PM
Hi,

Welcome to Ext.NET!

Thanks for the report.

I also can't see any config options to organize it. Hopefully, I missed something.

I have reported it to Sencha.
http://www.sencha.com/forum/showthread.php?238486

Lets wait what they will answer.

MWM2Dev
Aug 22, 2012, 8:55 PM
Hey,

Thanks for the reply! see they classified it as a bug, will find a work around for now using checkboxes and direct events to hide series using showall() and hideall() (or something similar using javascript)

One more question, different issue though I sometimes have null values in my lines coming from my database (this is intended sometimes we don't have data for a certain month)

is there a way for a line chart to show a gap? Now it just bumps to the 0 line and looks just silly (and it's actually wrong from a data standpoint) so the data we get is worked up like this

Month - Data - Data2
2012-01 - NULL - 12
2012-02 - 2 - 13
2012-03 - 4 - 4
etc.

is there a way for ext not to display the first point of data in a series? I haven't been able to get it to work sadly. I will add a code sample tomorrow if needed but the gist is in the text.

Daniil
Aug 23, 2012, 5:32 AM
Please keep one issue per one thread in the future. Just it's our policy to make the things clearly.



is there a way for a line chart to show a gap?

I am afraid LineSeries cannot be discrete. You could split it to several LineSeries. But, sure, most likely it will be inappropriate.


is there a way for ext not to display the first point of data in a series?

Maybe remove this point from a data before binding?

Daniil
Aug 23, 2012, 5:42 AM
I am afraid LineSeries cannot be discrete. You could split it to several LineSeries. But, sure, most likely it will be inappropriate.


I have asked on Sencha:
http://www.sencha.com/forum/showthread.php?238541

MWM2Dev
Aug 23, 2012, 3:43 PM
Created a small work around with javascript to use while a fix is being found

The javascript


//Javascript functions used to hide or show series in a chart
function highlightSeries(chart, serie) {
if (chart != undefined) {
App[chart].series.items[serie].highlightItem();
}
}
function unHightlightSeries(chart, serie) {
if (chart != undefined) {
App[chart].series.items[serie].unHighlightItem();
}
}
function hideOrShowSeries(chart, serie, legenditem) {
if (chart != undefined) {
if (App[chart].series.get(serie).seriesIsHidden) {
App[chart].series.get(serie).showAll();
legenditem.setAttribute("class", "LegendTerm");
} else {
App[chart].series.get(serie).hideAll();
legenditem.setAttribute("class", "LegendTermDisabled");
}
}
}

The C# code


/// <summary>
/// Class used to create legends for charts.
/// </summary>
public class LegendChart
{
/// <summary>
/// Returns a legend for the selected series and charts
/// </summary>
/// <param name="chartId">
/// The chart Id.
/// </param>
/// <param name="names">
/// The names.
/// </param>
/// <param name="colors">
/// The colors.
/// </param>
/// <param name="width">
/// The width.
/// </param>
/// <returns>
/// a panel containing a legend for the chart.
/// </returns>
public Panel Legend(string chartId, string[] names, Color[] colors, int width)
{
var legendPanel = new Panel
{
Width = width, Height = 100, CssClass = "chartLegend"
};

var numberColumns = width / 110;
var numberRows = (names.Length - 1) / numberColumns + 1;
var counter = 0;

legendPanel.Height = numberRows * 20;
for (var i = 0; i < numberColumns; i++)
{
if (counter > names.Length - 1)
{
break;
}
var column = new Panel();
column.Style.Add("display", "table-cell");
column.Style.Add("vertical-align", "top");
for (var j = 0; j < numberRows; j++)
{
if (counter > names.Length - 1)
{
break;
}

var term = new Panel();
term.CssClass = "LegendTerm";
term.Attributes.Add("onmouseover", "highlightSeries('" + chartId + "'," + counter + ")");
term.Attributes.Add("onmouseout", "unHightlightSeries('" + chartId + "'," + counter + ")");
term.Attributes.Add("onclick", "hideOrShowSeries('" + chartId + "'," + counter + ", this)");
var colorLit = new Literal();
colorLit.Text = @"<div class='LegendColor' style='background-color:" + ColorTranslator.ToHtml(colors[counter]) + ";' ></div><div style='width:90px;'>" + names[counter] + "</div>";
term.Controls.Add(colorLit);
column.Controls.Add(term);
counter = counter + 1;
}

legendPanel.Controls.Add(column);
}

return legendPanel;
}
}

and the code that calls on the legend creation



var names = new List<string>();
foreach (var lineData in pointDataList)
{
names.Add(lineData.name);
}
//Get the clientid substring to remove the app in front of it so we can use it in javascript.
var legendary = chartLegend.Legend(linechart.ClientID.Substring(4) , names.ToArray(), chartdrawer.ColorPalette, 600);


note that you are required to have an ID set for the chart else you won't be able to find it with the clientid supplied.

Let me know when the bug is fixed!

Thanks!

Daniil
Aug 23, 2012, 3:49 PM
Interesting, thanks for sharing! Could you explain a bit what does the workaround actually do?

MWM2Dev
Aug 23, 2012, 4:52 PM
hey!
Made a few screens of what it actually does, the code makes a new legend that is linked to the chart the id is supplied to (which opens up ideas for linking one legend to multiple graphs as well..)

The legend that is made has click events and mouse over (I don't have enough data in my current data set to show the mouse over more clearly)

4674
The new legend with rows and columns, the amount of rows

4675
When you click one of the items it changes the class so you can put css on it to change the style (I added some opacity in this example)
You can see it hides the top point for the testuser6 when clicked again the line will show again, its all javascript so it won't do any posts backs or anything like that.

It can probably be improved and it might contain some small bugs that need to be fixed, but its a good starting point if you run into this issue.

If there is more clarification needed just ask!

Daniil
Aug 23, 2012, 6:31 PM
Good, thanks for clarification!

Please clarify did you see the SmartLegend class that @Mitchell refers here?
http://www.sencha.com/forum/showthread.php?238486&p=875507&viewfull=1#post875507

Looks good as well.

Daniil
Aug 26, 2012, 8:59 AM
Regarding gaps in LineSeries. Sencha says it is slated for 4.2 release.
http://www.sencha.com/forum/showthread.php?238541

Daniil
Dec 10, 2012, 6:51 AM
Hi @MWM2Dev,

Again regarding gaps in LineSeries. Here is interesting post.
http://www.sencha.com/forum/showthread.php?179292&p=919706&viewfull=1#post919706

Daniil
Dec 10, 2012, 6:54 AM
Opened an Issue to track this defect, see:
https://github.com/extnet/Ext.NET/issues/77

Daniil
Dec 12, 2012, 5:34 AM
One more interesting post regarding gaps in a LineSeries.
http://www.sencha.com/forum/showthread.php?179292&p=920352&viewfull=1#post920352

It appears to be working well.

Example

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
Store s = this.Chart1.GetStore();
s.DataSource = new object[]
{
new
{
x = 0,
y = 0
},
new
{
x = 25,
y = 25
},
new
{
x = 50,
y = false
},
new
{
x = 75,
y = 75
},
new
{
x = 100,
y = 100
}
};
s.DataBind();
}
}

</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<ext:Chart
ID="Chart1"
runat="server"
Width="400"
Height="400">
<Store>
<ext:Store runat="server">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="x" />
<ext:ModelField Name="y" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<Axes>
<ext:NumericAxis Title="X" Fields="x" Position="Bottom" />
<ext:NumericAxis Title="Y" Fields="y" Position="Left" />
</Axes>
<Series>
<ext:LineSeries Titles="Chart" XField="x" YField="y" />
</Series>
</ext:Chart>
</form>
</body>
</html>

drkoh
Dec 20, 2012, 5:35 PM
Hi Danill,

just FYI, I tried your example for LineSeries and it indeed works, but not in Scatter series.

Regards

Daniil
Dec 21, 2012, 5:23 AM
Hi Danill,

just FYI, I tried your example for LineSeries and it indeed works, but not in Scatter series.

Regards

Hi @drkoh,

I don't understand well what you mean. Please clarify. Do you mean gaps?