I have two line series and how do I make points on both series selected at the same time? Basically, my chart has 2 y values sharing the same x value and I'm representing them as two series. I want to display both points as selected for a given X Value.
Hi there,Thanks for the reply. I'm doing that in
- (void)sChart:(ShinobiChart *)chart toggledSelectionForPoint:(SChartDataPoint *)dataPoint inSeries:(SChartSeries *)series atPixelCoordinate:(CGPoint)pixelPoint
SChartDataPoint* point1Series1 = [chart.datasource sChart:chart dataPointAtIndex:dataPoint.index forSeriesAtIndex:0];
point1Series1.selected = YES;
SChartDataPoint* point1Series2 = [chart.datasource sChart:chart dataPointAtIndex:dataPoint.index forSeriesAtIndex:1];
point1Series2.selected = YES;
When I print the selected state of both points after this line of code, they return 1(selected) but they don't seem to appear as selected on the chart only the one I selected on the chart on device seem to appear as selected though I'm calling redrawChart after that. Any help would be appreciated
I think that it's likely (and I'm guessing because I can't see your code) that your chart data source isn't returning a reference to a datapoint which is part of the chart, but instead generating a new datapoint object each time you request one.
In order to cope with this you can request the data points from the chart itself, via the dataSeries property on SChartSeries objects.
The following delegate method should perform the selection you require.
- (void)sChart:(ShinobiChart *)chart toggledSelectionForPoint:(SChartDataPoint *)dataPoint inSeries:(SChartSeries *)series atPixelCoordinate:(CGPoint)pixelPoint
{
// Selection details
NSInteger dataPointIndex = dataPoint.index;
BOOL selected = dataPoint.selected;
for (SChartSeries *chartSeries in chart.series) {
// If only one data point in the series can be selected at once, then deselect the rest
if(!series.togglePointSelection && selected) {
for(SChartDataPoint *dp in chartSeries.dataSeries.dataPoints) {
dp.selected = NO;
}
}
// Find the data point and perform the selection
SChartDataPoint *dp = chartSeries.dataSeries.dataPoints[dataPointIndex];
dp.selected = selected;
}
}
Hope that helps.
You should be able to set .selected on the datapoints and customise the series.style.selectedPointStyle properties to display points how you wish :)
Related
I've got 5 labels and for each label im assigning a random value from an array when a button is clicked. Im wanting the first label to be changed then the second and then the third etc... but cannot seem to get it working. I've tried a loop and a timer to try and make the effect
You can try this, you have to create an array of labels or a collection of labels.
func assignLabel(){
if yourArray.count > labelsArrays.count {
yourArray.removeFirst()
}
for i in 0..<yourArray.count {
labelsArrays[i].text = yourArray[i]
}
}
I want to hide the "top" part of all connector labels of a diagram. For this, I tried to set up a script, but it currently hides ALL labels (also the "bottom" labels which I want to preserve):
// Get a reference to the current diagram
var currentDiagram as EA.Diagram;
currentDiagram = Repository.GetCurrentDiagram();
if (currentDiagram != null)
{
for (var i = 0; i < currentDiagram.DiagramLinks.Count; i++)
{
var currentDiagramLink as EA.DiagramLink;
currentDiagramLink = currentDiagram.DiagramLinks.GetAt(i);
currentDiagramLink.Geometry = currentDiagramLink.Geometry
.replace(/HDN=0/g, "HDN=1")
.replace(/LLT=;/, "LLT=HDN=1;")
.replace(/LRT=;/, "LRT=HDN=1;");
if (!currentDiagramLink.Update())
{
Session.Output(currentDiagramLink.GetLastError());
}
}
}
When I hide only the top labels manually (context menu of a connector/Visibility/Set Label Visibility), the Geometry property of the DiagramLinks remains unchanged, so I guess the detailed label visibility information must be contained somewhere else in the model.
Does anyone know how to change my script?
Thanks in advance!
EDIT:
The dialog for editing the detailed label visibility looks as follows:
My goal is unchecking the "top label" checkboxes programmatically.
In the Geometry attribute you will find a partial string like
LLT=CX=36:CY=13:OX=0:OY=0:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=1:DIR=0:ROT=0;
So in between LLT and the next semi-colon you need to locate the HDN=0 and replace that with HDN=1. A simple global change like above wont work. You need a wild card like in the regex LLT=([^;]+); to work correctly.
Because I use Comboboxes that may contain text entries of very long size,
which leads to the combobox increasing its width far beyond reasonable size,
I am trying to give a maximum width to the combobox.
If I am doing this like this:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
render.property_width_chars() = 10;
render.property_ellipsize() = Pango::ELLIPSIZE_END;
pack_start(render, true);
}
};
The result will be an empty cell of the desired width, which seems logical since I did not specify which column to show. But how can I do this with that attempt? Using pack_start will just bypass the renderer...
Another approach is this one:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
pack_start(render, true);
set_cell_data_func(render, sigc::mem_fun(*this, &MyCombo::render_iter));
}
void render_iter(const TreeModel::const_iterator& iter) {
Glib::ustring data = get_string_from_iter(iter);
int desired_width_chars = 10; //for example
render.property_text() = ellipsize_string(data, desired_width_chars);
}
};
Using that approach, it works, but the text in the popup (what opens up when u click the combobox) is also shortened which is not what I want (obviously the user should be able to read the whole string and I dont care about the popup widht.)
Can you please help me with this? I would be happy for any advice/alternative solutions.
Regards tagelicht
NOTE: set_wrap_width is a function that wraps the total number of entries in the combo box over a number of columns specified; it does not answer the question.
Using set_wrap_width(1) | Using set_wrap_width(5)
Following Noup's answer as a guide I managed to get the below code; which directly answers the question and its requirements (C++/Gtkmm).
// Get the first cell renderer of the ComboBox.
auto v_cellRenderer = (Gtk::CellRendererText*)v_comboBox.get_first_cell();
// Probably obsolete; Sets character width to 1.
v_cellRenderer->property_width_chars() = 1;
// Sets the ellipses ("...") to be at the end, where text overflows.
// See Pango::ELLIPSIZE enum for other values.
v_cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_END;
// Sets the size of the box, change this to suit your needs.
// -1 sets it to automatic scaling: (width, height).
v_cellRenderer->set_fixed_size(200, -1);
Result (image):
Result of code
BE AWARE: Depending on where you perform the above code; either all the cells will be the same size, or just the box itself (intended).
From experimenting, I've found:
In the parent object constructor: All cell sizes are the same.
In a separate function: Only the first cell (the box) is affected.
I'd recommend you put the code in a function that's connected to the comboBox's changed signal, such as:
v_comboBox.signal_changed().connect(sigc::mem_fun(*this, &YourClass::comboBox_changedFunction));
This may be what you are looking for:
cell_renderer_text.set_wrap_width(10)
This is for Python, but you get the idea :-)
Unfortunately, the documentation is scarce. I found this by poking around in Anjuta/Glade.
Edit:
the docs are here. They are not overly helpful, but they do exist.
As an alternative, the following works for me without having to set wrap_width nor to subclass ComboBox (in Gtk#):
ComboBoxText cb = new ComboBoxText();
cb.Hexpand = true; //If there's available space, we use it
CellRendererText renderer = (cb.Cells[0] as CellRendererText); //Get the ComboBoxText only renderer
renderer.WidthChars = 20; //Always show at least 20 chars
renderer.Ellipsize = Pango.EllipsizeMode.End;
Note: I'm using Expand to use space if it's available. If you just want to keep the combo box on a fixed width, just remove that bit.
I just started using AmCharts and have setup two line plots, one on top of the other, with their respective scrollbars.
Now, I want to "link" the scrollbars of both plots, so that if I move the scrollbar on the chart1, I'll get the same date range on the chart2. I imagine this shouldn't be too difficult with a listener, a get value function and a set value function, but I'm unable to find how to get the start/end values of the scrollbar so that I can play with them.
Any help would be appreciated.
thanks
There is a demo for this in the AmCharts Knowledge Base
https://www.amcharts.com/kbase/share-scrollbar-across-several-charts/
This is the code that is syncing the scrollbars, (I have added the annotations):
Create an array to populate with your charts
var charts = [];
Create how ever many charts you need
charts.push(AmCharts.makeChart("chartdiv", chartConfig));
charts.push(AmCharts.makeChart("chartdiv2", chartConfig2));
charts.push(AmCharts.makeChart("chartdiv3", chartConfig3));
Iterate over the charts, adding an event listener for "zoomed" which will share the event handler
for (var x in charts) {
charts[x].addListener("zoomed", syncZoom);
}
The event handler
function syncZoom(event) {
for (x in charts) {
if (charts[x].ignoreZoom) {
charts[x].ignoreZoom = false;
}
if (event.chart != charts[x]) {
charts[x].ignoreZoom = true;
charts[x].zoomToDates(event.startDate, event.endDate);
}
}
}
I am trying my first iphone app. I am stuck now. I have two label that display seperate random numbers. I used a button and IBAction to generate the numbers then pass them to the label. Now I need to determine when the two numbers match and then print "match" in another label. I am trying all kinds of different things but somehow I am missing something. If anyone can help explain how to do this form a code point of view and hooking it into interface builder that would be awesome! Thanks
In the method where you get and show the random numbers you simply compare them and change the text in the third label accordingly.
- (IBAction)buttonPressed {
// Generate the 2 random numbers and show them in the labels here.
// Then compare them and show the result in the third label:
if (randomNumber1 == randomNumber2) {
thirdLabel.text = #"Match";
} else {
thirdLabel.text = #"No Match";
}
}