I've got a RadCartesianChart3D that uses a SurfaceSeries3D to show a colorized surface I've attached a sample image to show how it looks now ("Current_Surface.png")
- I colorize this surface using a SurfaceSeries3dValueGradientColorizer.
- I build the colorizer in code-behind one single time. It consists of 64 hard-coded color values that I use to colorize the my surface.
- The gradient stops are evenly distributed throughout the 0.0 to 1.0 range. I just manually set each GradientStop's "Offset" value to be (1.0 / 64.0) apart
This all works very well and looks great. It produces the image I referred to above.
Here is the XAML I use.
<
tk:RadCartesianChart3D.Series
>
<
tk:SurfaceSeries3D
ItemsSource
=
"{Binding Points}"
XValueBinding
=
"X"
YValueBinding
=
"Y"
ZValueBinding
=
"Z"
x:Name
=
"Series"
>
<
tk:SurfaceSeries3D.Colorizer
>
<
tk:SurfaceSeries3DValueGradientColorizer
x:Name
=
"Colorizer"
IsAbsolute
=
"False"
/>
</
tk:SurfaceSeries3D.Colorizer
>
</
tk:SurfaceSeries3D
>
</
tk:RadCartesianChart3D.Series
>
And here is how my XAML builds the GradientStops
// "Colors" is an array of 64 custom colors.
// Return an evenly distributed array of them for gradient stops.
var step = 1.0 / Colors.Length;
var stops = Colors.Select((color, index) => new GradientStop(color, index * step));
return new GradientStopCollection(stops);
But now I have a new requirement. I need to add a RadSlider that allows the user to dynamically change the colors instantaneously. The slider sets "cut-off" values distribution of the colors, limiting the range to a subset of 1.0. The visual effect is to highlight certain values. Basically I am emulating something that is already done a different application of ours (that app uses OpenGL).
To illustrate, I have also attached an image ("Desired_Surface.png") of this alternate application (the one that already has this slider) and the same surface showing. You can see the the user has adjusted the bottom slider upwards and this has totally compressed the color distribution. (You can even see the compressed distribution in the slider itself, though I don't need that).
My problem is that I cannot see how to emulate this with SurfaceSeries3D without using Deferred Dragging . The user needs to see the colors change immediately as he/she adjusted either of the sliders indicators; But the only way I can see to implement this is far too slow for anything but deferred dragging.
First I tried binding the Colorizer's GradientStop property. As you no doubt already know, that is not allowed by WPF
<
tk:SurfaceSeries3D.Colorizer
>
<
tk:SurfaceSeries3DValueGradientColorizer
IsAbsolute
=
"False"
GradientStops
=
"{Binding GradientStops}"
/>
Then I tried declaring all 64 gradient stops directly in XAML and binding each one's GradientStop.Offset to a backing view-model property but that is also not allowed (because Gradient stops must be Freezable and always sorted)
<
tk:SurfaceSeries3D.Colorizer
>
<
tk:SurfaceSeries3DValueGradientColorizer
IsAbsolute
=
"False"
>
<
tk:SurfaceSeries3DValueGradientColorizer.GradientStops
>
<
GradientStopCollection
>
<
GradientStop
Color
=
"sc# 1.0, 0.0, 0.0, 0.5625"
Offset
=
"{Binding Offset_0}"
/>
<
GradientStop
Color
=
"sc# 1.0, 0.0, 0.0, 0.6250"
Offset
=
"{Binding Offset_1}"
/>
So the only way I could get this working was to completely rebuild the entire Colorizer every single time the user adjusts the slider. I construct 64 new Gradient stops with the new Offset values and put them into a new GradientStop collection. Unfortunately, this is far, far too laggy and slow. It's too much work to do for a slider drag. So I am left with using deferred dragging. But that's not what my boss wants.
Is there any other approach I might take to speed up the adjustment of the colors?