OxyPlot legend items managing - wpf

is there any way to manage items in legend? I mean e.q. remove some items from legend but not from whole plot? I know that each serie in plot is linked with one item in legend, but i want to break this rule and put to legend only selected series.
Thanks for your request.

If you don't assign a title to the series (LineSeries, etc), it won't be represented on the legend:
var plotModel = new PlotModel();
plotModel.LegendTitle = "Legend";
plotModel.LegendPosition = LegendPosition.RightBottom;
plotModel.Series.Add(new LineSeries
{
ItemsSource = someItemSource,
Color = OxyColors.Red,
//Title = "title" <- Title commented
});
Starting v2.0.1, the legend doesn't automatically appear and all PlotModel.LegendXxx members have been removed. You now have to manually add one legend:
var plotModel = new PlotModel();
plotModel.Legends.Add(new Legend() {
LegendTitle = "Legend",
LegendPosition = LegendPosition.RightBottom,
});
plotModel.Series.Add(new LineSeries
{
ItemsSource = someItemSource,
Color = OxyColors.Red,
//Title = "title" <- Title commented
});

Related

Can't get custom images to display in Azure Maps as Symbols

I really can't find any good documentation or any good samples on how to do this.
Here is my code. This is running in an Asp.net Core View.
var imageMarker = "https://unpkg.com/leaflet#1.7.1/dist/images/marker-icon.png";
for (var i = 0; i < locationData; i++) {
let imageName = 'image' + i;
map.imageSprite.add(imageName, imageMarker).then(function () {
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Create a point feature and add it to the data source.
datasource.add(new atlas.data.Feature(new atlas.data.Point(i.longitude, i.latitude), {
name: i.name
}));
//Add a layer for rendering point data as symbols.
map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
//Pass in the id of the custom icon that was loaded into the map resources.
image: imageName,
//Optionally scale the size of the icon.
size: 0.5
},
textOptions: {
//Add some text
textField: name,
//Offset the text so that it appears on top of the icon.
offset: [0, -2]
}
}));
});
}
I'm not getting any errors. The Symbols just don't appear on the map.
The sample linked below works in my map.events.add ready function.
Image Sprite sample
Any help is much appreciated! Thanks!
Here is what ended up working for me. I worked with Microsoft Support on this. locationData contains the image, longitude and latitude. The min and max of both longitude and latitude is passed in as well to set the camera boundry. The biggest issue with my original code was setting iconOptions size to 0.5. The plugin did not like that. It's now set to 1.
function addMarkerSymbols(locationData, min_long, min_lat, max_long, max_lat)
{
map.setCamera({
bounds: [min_long, min_lat, max_long, max_lat],
padding: 50
});
$.each(locationData, function (i, item)
{
map.imageSprite.add('default-icon' + i, item.locationImage);
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Add a data set to the data source.
datasource.add(new atlas.data.Feature(new atlas.data.Point([item.longitude, item.latitude]), null));
//Create a symbol layer to render the points.
layer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
//The map control has built in icons for bar, coffee and restaurant that we can use.
image: 'default-icon' + i,
anchor: 'center',
allowOverlap: true,
size: 1
}
});
map.layers.add(layer);
});
}

How to make a custom legend in angular-chart.js Pie Chart

I used angular-chart.js in my website to create a Pie chart, and I would like to customize the legend. By default, the legend shows the color and the label. (As shown in the picture below) I would like to add the value/data of that label, like what it shown in the tooltip of the chart.
This is my HTML code:
<canvas id="pie" class="chart chart-pie"
chart-data="chartData" chart-labels="chartLabels" chart-options="chartOptions">
</canvas>
Based on the angular-chart.js documentation, legend is now a Chart.js option so the chart-legend attribute has been removed.
That is why, in my JS code I've tried to add generateLabels, just in case this is what I need to customize the legend:
$scope.chartOptions = {
legend: {
display: true,
labels: {
generateLabels: function(chart){
console.log(chart.config);
}
}
}
};
But whenever I add this lines, it will not show the chart. I think it is an error or something. And I'm not sure, if generateLabels is the right option that I needed.
Can somebody teach me the right way to customize the legend to achieve what I wanted?
Thanks in advance!
Let me try shedding some light/answering your question:
generateLabels: does make custom labels,and replaces templates from v1 but in order to use it you have to get your chart information and reimplement legend labels adhering to the Legend Item Interface found in the docs and code. Sounds a bit cryptic, but in practice is somehow simple and goes like this:
var theHelp = Chart.helpers;
// You need this for later
// Inside Options:
legend: {
display: true,
// generateLabels changes from chart to chart, check the source,
// this one is from the doughnut :
// https://github.com/chartjs/Chart.js/blob/master/src/controllers/controller.doughnut.js#L42
labels: {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var custom = arc && arc.custom || {};
var getValueAtIndexOrDefault = theHelp.getValueAtIndexOrDefault;
var arcOpts = chart.options.elements.arc;
var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
return {
// And finally :
text: ds.data[i] + "% of the time " + label,
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i
};
});
}
return [];
}
}
}
Result:
Codepen: Chart.js Pie Chart Custom Legend Labels
There are other alternatives, if you notice on the pen/pie, the slices also have data information, that is from a plugin (check the pen)
Still another option, is to render the legend labels off canvas,for instance:
myPieChart.generateLegend();
Which gives you this Html:
"<ul class='0-legend'><li><span style='background-color:black'> </span>she returns it </li><li><span style='background-color:white'></span>she keeps it</li></ul>"
I haven't tried it, but I think you can modify it with the global method for your data Legend on the callback an it will give you a block of Html you can insert off canvas.

ExtJS 6 toggle legend fields

Now legend in EXTJS works in such way: it shows all available legend fields and appropriate series and you can enable/disable any of them. I want to make that only one legend item can be enabled in one time. E.g. you have chart with 2 legend items (with 2 series), only first item is active on chart load and then if you want to active second item then first item becomes automatically disabled.
Here is chart fiddle with native ExtJS behaviour:
https://fiddle.sencha.com/#fiddle/1b7d
Please, post ideas how can I make it work as I described before.
If you have a look at the legend source code, freely available in your Ext directory or in the Sencha docs, you find that you can override that toggleItem method in such a way that only one selection is allowed.
The basics should be something like
toggleItem: function (index) {
var store = this.getStore(),
record = store.getAt(index);
store.query("disabled", false).each(function(record) {record.set("disabled", true) });
record.set("disabled", false);
}
but it doesn't work exactly as expected. Perhaps you can pave your way along from there.
this can be easily achieved with using legend type dom, and looping and setting every other legend (button) disabled, as followed -
legend: {
docked: 'bottom',
type: 'dom',
listeners: {
itemclick: function(obj, record, item, index) {
var i = 0,
records = obj.getStore().getRange();
for(i=0; i < records.length; i++){
i === index ? records[i].set('disabled', false) : records[i].set('disabled', true);
}
}
}
}

WPF DataVisualization Stacked Column Chart Binding

i will generate Stacked column chart, which will display on the x-axis cities and on the y-axis are count of genders in column. How to binding chart and this data:
List<Cities> Cities = new List<Cities>()
{
new Cities
{
Name = "Paris",
Genders = new Genders()
{
Man = 350000,
Woman = 436000
}
},
new Cities()
{
Name = "London",
Genders = new Genders()
{
Man = 698056,
Woman = 736982
}
}
};
I am trying to generate Series:
int i = 0;
foreach (var city in Cities)
{
Series s1 = new ColumnSeries();
s1.Title = city.Name;
s1.Name = "S"+i;
StackedColumnChart.Series.Add(s1);
i++;
}
i dont know how to binding data. Thanks
you can try to download a trial version of LightningChart with included demonstration examples for WinForms, WPF with Non-bindable, Semibindable and Fully Bindable examples.
You can easily look at the source code examples, e.g. ExampleStackedBars.
In a code behind you can create a field, which will be binded to the chart BarSeriesCollection property:
public static readonly DependencyProperty BarSeriesProperty =
DependencyProperty.Register(
"BarSeries",
typeof(BarSeriesCollection),
typeof(ExampleStackedBars)
);
public BarSeriesCollection BarSeries
{
get { return GetValue(BarSeriesProperty) as BarSeriesCollection; }
set { SetValue(BarSeriesProperty, value); }
}
And after create a new instance and add data to the collection:
BarSeries = new BarSeriesCollection();
GenerateData();
In XAML you can easily bind it using this line:
<lcusb:LightningChartUltimate.ViewXY>
**<lcusb:ViewXY BarSeries="{Binding BarSeries}">**
<lcusb:ViewXY.BarViewOptions>
<lcusb:BarViewOptions BarSpacing="30" Grouping="ByIndexFitWidth" Stacking="Stack" IndexGroupingFitGroupDistance="20"/>
</lcusb:ViewXY.BarViewOptions>
</lcusb:ViewXY>
</lcusb:LightningChartUltimate.ViewXY>
</lcusb:LightningChartUltimate>
or set binding path in the property tree
Example in Sparrow toolkit is for other chart type. i need Stacked bar chart. My graph must in x-axis cities and for each city must be multiple values in column. This is my chart:
<charting:Chart
Grid.Column="0"
Grid.Row="0"
x:Name="StackedColumnChart"
Title="Stacked Column"
Margin="5">
<charting:StackedColumnSeries>
</charting:StackedColumnSeries>
</charting:Chart>
I dont know what is series. Series is columns? How to assign multiple value (in my example genders) to one column?

Nested Grid IN EXTJS

HI
How to design Nested grids in ExtJS
Please provide some samples(How to use RowExpander in ExtJS GridPanel)
Try something like this:
//Create the Row Expander.
var expander = new Ext.ux.grid.RowExpander({
tpl : new Ext.Template('<div id="myrow-{Id}" ></div>')
});
//Define the function to be called when the row is expanded.
function expandedRow(obj, record, body, rowIndex){
//absId parameter for the http request to get the absence details.
var absId = record.get('Id');
var dynamicStore = //the new store for the nested grid.
//Use Id to give each grid a unique identifier. The Id is used in the row expander tpl.
//and in the grid.render("ID") method.
var row = "myrow-" + record.get("Id");
var id2 = "mygrid-" + record.get("Id");
//Create the nested grid.
var gridX = new Ext.grid.GridPanel({
store: dynamicStore,
stripeRows: true,
columns: [
//columns
],
height: 120,
id: id2
});
//Render the grid to the row expander template(tpl).
gridX.render(row);
gridX.getEl().swallowEvent([ 'mouseover', 'mousedown', 'click', 'dblclick' ]);
}
//Add an expand listener to the Row Expander.
expander.on('expand', expandedRow);
You can find more information on this Here
How to use RowExpander in grid? Here's an example: http://dev.sencha.com/deploy/dev/examples/grid/grid-plugins.html
More examples can be found from http://dev.sencha.com/deploy/dev/examples/
It is possible to do it as the others have mentioned, however I recommend against it.
Reasons:
Memory leaks due to the sub-grids not being destroyed properly.
Selection model doesn't work correctly
Events get messed up.

Resources