EDIT: добавлен кодItemsControl Bar Chart Scaling баров
Кроме того, так как DateTimes не очень DateTimes (Strings в формате чч: мм: сс) я решил просто использовать строки вместо и использовать TimeSpan для извлечения totalMinutes.
<ObjectDataProvider x:Key="odpLbGrafiek" ObjectType="{x:Type myClasses:GrafiekBar}" MethodName="GetDataGrafiek"/>
<DataTemplate x:Key="GrafiekItemTemplate">
<Border Width="Auto" Height="Auto">
<Grid>
<Rectangle StrokeThickness="0" Height="30"
Margin="15"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="{Binding Value}"
Fill="{Binding Fill}">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="20" />
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
</DataTemplate>
Заполнение фактически дает размер на панели гистограммы.
ItemsControl:
<ItemsControl x:Name="icGrafiek"
Margin="20,3,0,0"
ItemsSource="{Binding Source={StaticResource odpLbGrafiek}}"
ItemTemplate="{DynamicResource GrafiekItemTemplate}"
RenderTransformOrigin="1,0.5" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.RowSpan="6">
<ItemsControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</ItemsControl.RenderTransform>
</ItemsControl>
Следующий метод вызывается в DataBinding. Там bar.Value дает значение для значения Width в datatemplate, которое дает размер бара.
public ObservableCollection<GrafiekBar> GetDataGrafiek()
{
var converter = new System.Windows.Media.BrushConverter();
Double maxValueStilstanden = GetLargestValueStilstanden();
TimeSpan tsMaxValue = TimeSpan.Parse(maxValueStilstanden.ToString());
totalMinutesMaxValue = tsMaxValue.TotalMinutes;
//calculate % of stilstanden Values
foreach(String t in stilStandenList)
{
TimeSpan ts = TimeSpan.Parse(t);
Double totalMin = ts.TotalMinutes;
totalMin = totalMin/totalMinutesMaxValue * 100;
valuesChartPercentage.Add(totalMin);
}
for (int j = 0; j < valuesChartPercentage.Count; j++)
{
GrafiekBar bar = new GrafiekBar();
bar.Value = valuesChartPercentage[j];
bar.Fill = converter.ConvertFromString(kleuren[j]) as Brush;
listGrafiek.Add(bar);
}
return listGrafiek;
}
Другой проблемой является фактически ширина (размер бара). Я действительно должен сделать * 10000, чтобы получить визуальное представление о баре.
Я использую ItemsControl что стилизованный так выглядит гистограмму.
Так, например, массив с 5 значениями, идущими от 1 до 5, создает 5 баров с различными размерами бара и с каждым другим цветом. похожи друг на друга в следующем примере http://www.c-sharpcorner.com/uploadfile/mahesh/bar-chart-in-wpf/
Проблема:
Моя проблема с масштабом проклейки стержней (ширины свойства в этом случае, так что INT/двойное значение требуется).
- Моя программа записывает несколько DateTimes в ЧЧ: мм: сс
- Стержни должны быть расширены на этих DateTimes
Например я мог иметь бар с 01:22:11 или его бар с 00:01:11 до максимальной суммы 6.
Какой был бы лучший способ масштабирования этих значений DateTime до определенного двойного значения? Это значение будет использоваться для указания размера панели на диаграмме.
Угадайте, что я ищу какой-то расчет, который вычисляет все мои значения одинаково, поэтому я не получаю внезапное значение, которое безумно велико и выходит из моего интерфейса.
Самое чистое решение состоит в том, что все бары сравниваются друг с другом, а когда каждый изменяет другой, он растет/сжимается, но это еще не требуется, хотя это не так сложно, как кажется.
Барный символ сам по себе не должен быть слишком точным, он служит только для того, чтобы получить общую картину ситуации. Точные значения будут записаны в базе данных.
Любые предложения приветствуются!
Спасибо PeterP.
Спасибо за ответ, можно ли проиллюстрировать часть кода? Моя программа запускает таймер, и его возможные значения обновляются каждые 5 секунд. Возможно также время в секундах. – PeterP
@PeterP Я бы использовал конвертер 'ItemsSource', который ожидает' ObservableCollection ', а также базовый параметр datetime. В конвертере я бы начал, перейдя по списку и найдя самую большую дату. Возьмите разницу в минутах/днях/часах/секундах между базовой датой и самой большой датой и сохраните ее где-нибудь, чтобы использовать ее как 100%. Теперь создайте новый список для хранения возвращаемых значений. Пронумеруйте исходный список, получите количество минут/дней/часов/сек между этой датой и базовой датой и разделите его на 100% число и добавьте результат в список возврата. Возврат нового списка в IC –
Rachel
@PeterP Таймер не будет проблемой, если вы используете 'ObservableCollection' вместо 'List ', так как 'ObservableCollection' будет реагировать на уведомления об изменениях, которые может запускаться таймер. –
Rachel