Is there a way to open a chart after it's created and added to a layer through the API? I can't find an "Open" method or anything similar on the CIMChart class or a way to open a TOC item by name. The closest thing I can find is to select the layer in the TOC and activate the TOC pane so the user sees that it's created. I'm creating a chart following the process in Public classes to create a chart through the API.
In ArcMap we created a chart (IDataGraphT instance) and added it to an IDataGraphWindow2 instance, then called Show.
Shameless bump :-). I was hoping this would be implemented in 2.6, but I still can't find any way to do it. Tim Whiteaker alluded to this in How to refresh a layer's chart list in the map's table of contents, which is now marked as answered, so any additional guidance would be super helpful. According to the Live Visual Tree in VS2019, charts use a ChartPaneView, which is an internal class. Can this be made public? Alternatively, can we access the TOC item and simulate a double-click?
We have an ArcMap workflow where users can create multiple charts on the same feature class, and we have a manager that allows them to open, delete, etc. We are unable to migrate this to Pro because we can't open the charts directly through code. Our current workaround is to include verbiage on the manager UI so the user knows where to find the charts, but this is not ideal.
Thanks for raising this question. I too need the ability to open a chart through the API. Have you had any additional information from ESRI?
Yes, I am surprised that there still seems to be no development on this
Thanks for raising this question. I too need the ability to open a chart through the API. Have you had any additional information from ESRI?
@Anonymous Userand @Laxmikanth I've never heard anything back. Have y'all been able to come up with anything?
I have not heard anything as well.
I still have no solution either
Any development on this? Would be useful.
I think the official api for open chart is not available. In fact, you can find that function for open pane is in protected acess level in the source code.
However, given that create chart also has the side effect of opening in the pane. I have alternate solution that can mimic the open chart function. The approach is to create new chart (which also open it), then copy the old configuration to the newly created (and opened) chart, then delete the old one, effectively gives a net effect of "opening" a chart
First, locate and select the standalonetable
var map = MapView.Active?.Map;
if (map == null) return;
// Find your standalone table by name
var myTable = map.StandaloneTables
.FirstOrDefault(t => t.Name.Equals("standaloneTableName", StringComparison.OrdinalIgnoreCase));
if (myTable != null)
{
// Activate it → selects it in the TOC
QueuedTask.Run(() =>
{
myTable.Activate();
});
}
// This command create chart based on the selected standalonetable
FrameworkApplication.ExecuteCommand("esri_mapping_pasteMapMemberChartsButton")
Then create a new chart by ICommand, which has the side effect of opening in the chart pane
// This command Create line chart based on the selected standalone table, which also open the chart
var createLineChartCommand = FrameworkApplication.GetPlugInWrapper("esri_charts_CreateLineChartButton") as ICommand;
if (createLineChartCommand == null || !createLineChartCommand.CanExecute(null))
{
Debug.WriteLine("Create line chart command not available.");
return;
}
createLineChartCommand.Execute(null);
Now , the newly created chart is opened, but it does not have the configuration we want (which is hold by CIMChart object), so the next step is to move the CIMChart to the newly created chart, then delete the old chart
await QueuedTask.Run(async () =>
{
try
{
var tableDefinition = firstTable.GetDefinition() as TableDefinition;
if (tableDefinition == null) return;
var charts = tableDefinition.Charts?.ToList();
const string chartID = "CrossSectionAverageVelocityChart";
if (!chartDict.ContainsKey(chartID))
{
System.Diagnostics.Debug.WriteLine($"Chart ID '{chartID}' not found in chartDict.");
return;
}
string oldChartName = chartDict[chartID];
var oldChart = charts.FirstOrDefault(c => c.Name == oldChartName);
if (oldChart == null)
{
System.Diagnostics.Debug.WriteLine($"Old chart '{oldChartName}' not found.");
return;
}
// The LAST chart is the newly created one
var newChart = charts.Last();
if (newChart == null || newChart.Name == oldChartName)
{
System.Diagnostics.Debug.WriteLine("New chart is invalid or same as old.");
return;
}
// Remove the old chart
charts.Remove(oldChart);
// Crucial!! Here either need a MessageBox or progress dialog
MessageBox.Show("This message box is needed such that the chart is loaded properly, content is not impotant");
// Commit updated chart list
tableDefinition.Charts = charts.ToArray();
firstTable.SetDefinition(tableDefinition);
chartDict[chartID] = newChart.Name;
}
catch (Exception ex)
{
Debug.WriteLine($"Error: {ex.Message}");
}
});Note that because the chart is created and then removed every time it is opened using this approach, the Name property of the chart is therefore keep changing, I store the Name in a dictionary call "chart_dict" to keep track of the "Name" so that the chart can be retreived with the "Name". Also note that a message box or progress dialog (progress dialog not work in debug mode) is needed in the middle of the process so that the chart can be rendered correctly.