AlexanderP Posted March 5 Posted March 5 Добрый день! Можно как то добавить новый Axes, чтобы он был справа, я не смог найти примеры на форуме Хочется повторить вот такой график Слева BarSeries по кол-ву и с привязкой к левой Axes Справа LineSeries по процентам и с привязкой к правой Axes Quote
AlexanderP Posted March 8 Author Posted March 8 Добрый день! Будет ли какое решение моего вопроса ? Quote
Sherzod Posted March 10 Posted March 10 1. UniChart1 2. procedure TMainForm.CreateDemoData; var CDS: TClientDataSet; begin CDS := TClientDataSet.Create(Self); // создаём поля with CDS.FieldDefs do begin Add('Category', ftString, 50); Add('Count', ftInteger); Add('Percent', ftFloat); end; CDS.CreateDataSet; CDS.AppendRecord(['1200-1400', 10520, 41]); CDS.AppendRecord(['1000-1200', 5439, 62]); CDS.AppendRecord(['1400-1600', 4339, 79]); CDS.AppendRecord(['Other', 3775, 94]); CDS.AppendRecord(['<1000', 1700, 100]); DataSource1.DataSet := CDS; UniBarSeries1.DataSource := DataSource1; UniBarSeries1.XLabelsSource := 'Category'; UniBarSeries1.YValues.ValueSource := 'Count'; UniLineSeries1.DataSource := DataSource1; UniLineSeries1.XLabelsSource := 'Category'; UniLineSeries1.YValues.ValueSource := 'Percent'; end; 3. procedure TMainForm.UniFormCreate(Sender: TObject); begin CreateDemoData; end; 4. UniChart1.ClientEvents.UniEvents -> function chart.beforeInit(sender, config) { config.innerPadding = { left: 4, right: 10, top: 40 }; config.axes = [{ type: 'numeric', position: 'left', fields: ['A'], title: 'Count', grid: true },{ type: 'numeric', position: 'right', fields: ['B'], minimum: 0, maximum: 100, title: 'Percent', label: { renderer: function(v){ return v + '%'; } } },{ type: 'category', position: 'bottom', fields: ['LL'] }]; Ext.Array.each(config.series || [], function(series){ // BAR SERIES if (series.type === 'bar') { series.label = { field: 'A', display: 'outside', orientation: 'horizontal', padding: 10, renderer: function(v){ return Ext.util.Format.number(v,'0,000'); } }; } // LINE SERIES if (series.type === 'line') { series.axis = 'right'; series.style = { strokeStyle: '#7cb342', lineWidth: 2 }; series.marker = { radius: 4 }; series.label = { field: 'B', display: 'over', padding: 8, renderer: function(v){ return v + '%'; } }; series.renderer = function(sprite, cfg, rendererData, index) { var rec = rendererData.store.getAt(index); var val = rec.get('B'); if (val >= 80) { cfg.fillStyle = '#d9534f'; cfg.strokeStyle = '#d9534f'; } else { cfg.fillStyle = '#7cb342'; cfg.strokeStyle = '#7cb342'; } return cfg; }; } }); } Quote
AlexanderP Posted March 12 Author Posted March 12 Добрый день! А как можно принудительно обновить Chart, чтобы сработали события series.renderer Хочу чтобы при выделении столбика он раскрашивался в другой цвет, для этого добавил в chart.beforeInit переменную sender.select_index = 0; и series.renderer = function(sprite, cfg, rendererData, index) для BarSeries function chart.beforeInit(sender, config) { sender.select_index = 0; config.innerPadding = { left: 4, right: 10, top: 40 }; config.axes = [{ type: 'numeric', position: 'left', fields: ['A'], title: 'Count', grid: true },{ type: 'numeric', position: 'right', fields: ['B'], minimum: 0, maximum: 100, title: 'Percent', label: { renderer: function(v){ return v + '%'; } } },{ type: 'category', position: 'bottom', fields: ['LL'] }]; Ext.Array.each(config.series || [], function(series){ // BAR SERIES if (series.type === 'bar') { series.label = { field: 'A', display: 'outside', orientation: 'horizontal', padding: 10, renderer: function(v){ return Ext.util.Format.number(v,'0,000'); } }; series.renderer = function(sprite, cfg, rendererData, index) { cfg.fillStyle = 'green'; cfg.strokeStyle = 'green'; if (index === sender.select_index) { cfg.fillStyle = 'blue'; cfg.strokeStyle = 'blue'; } return cfg; }; } // LINE SERIES if (series.type === 'line') { series.axis = 'right'; series.style = { strokeStyle: '#7cb342', lineWidth: 2 }; series.marker = { radius: 4 }; series.label = { field: 'B', display: 'over', padding: 8, renderer: function(v){ return v + '%'; } }; series.renderer = function(sprite, cfg, rendererData, index) { var rec = rendererData.store.getAt(index); var val = rec.get('B'); if (val >= 80) { cfg.fillStyle = '#d9534f'; cfg.strokeStyle = '#d9534f'; } else { cfg.fillStyle = '#7cb342'; cfg.strokeStyle = '#7cb342'; } return cfg; }; } }); } также добавил обработчик в ExtEvents function chart.itemmousedown(chart, item, event, eOpts) { chart.select_index = item.index; chart.redraw; } И вот при вызове chart.redraw; ничего не происходит если же в легенде выключить серию и потом включить, то столбик выделяется, т.е. срабатывает series.renderer Видео-12-03-2026 213950.mp4 Quote
AlexanderP Posted March 13 Author Posted March 13 1 hour ago, Sherzod said: Этот пост может помочь: я видел этот пост и у меня не получилось повторить, чтобы все работало если рассматривать это событие, то здесь мне интересно только это, выделил жирным function chart.boxready(sender, width, height, eOpts) { this.series.items[0].addListener('itemmousedown', function(el) { var series = this.chart.series.get(0); series.highlight = true; series.unHighlightItem(); series.cleanHighlights(); series.highlightItem(el); series.highlight = false; var rec = MainForm.UniDBGrid1.getStore().findRecord('2', el.storeItem.data.LL); if (rec) { MainForm.UniDBGrid1.getSelectionModel().select(rec); }; }) } я преобразовал под свою задачу так, хотя можно сразу завязаться на событие function chart.itemmousedown(chart, item, event, eOpts) function chart.boxready(sender, width, height, eOpts) { if (sender.series) { Ext.each(sender.series, function(series, index) { series.addListener('itemmousedown', function(el) { series.highlight = true; series.unHighlightItem(); series.cleanHighlights(); series.highlightItem(el); series.highlight = false; }); }); } } но в любом случае этот код не работает, ругается series.unHighlightItem is not a function series.cleanHighlights is not a function series.highlightItem is not a function Quote
AlexanderP Posted March 21 Author Posted March 21 On 3/13/2026 at 12:31 PM, Sherzod said: Я попробую проверить. Sherzod получилось проверить ? Quote
Sherzod Posted March 24 Posted March 24 On 3/21/2026 at 11:59 AM, AlexanderP said: Sherzod получилось проверить ? Пока безрезультатно. Quote
Sherzod Posted March 26 Posted March 26 On 3/21/2026 at 11:59 AM, AlexanderP said: Sherzod получилось проверить ? Решение: 1. function chart.beforeInit(sender, config) { config.innerPadding = { left: 4, right: 10, top: 40 }; config.axes = [{ type: 'numeric', position: 'left', fields: ['A'], title: 'Count', grid: true }, { type: 'numeric', position: 'right', fields: ['B'], minimum: 0, maximum: 100, title: 'Percent', label: { renderer: function(v) { return v + '%'; } } }, { type: 'category', position: 'bottom', fields: ['LL'] }]; Ext.Array.each(config.series || [], function(series) { // BAR SERIES if (series.type === 'bar') { series.label = { field: 'A', display: 'outside', orientation: 'horizontal', padding: 10, renderer: function(v) { return Ext.util.Format.number(v, '0,000'); } }; series.renderer = function(sprite, cfg, rendererData, index) { var chart = sender; if (chart._selectedIndex !== undefined && chart._selectedIndex === index) { cfg.fillStyle = '#ff9800'; // выбранный } else { cfg.fillStyle = '#5fa2dd'; // обычный } return cfg; }; } // LINE SERIES if (series.type === 'line') { series.axis = 'right'; series.style = { strokeStyle: '#7cb342', lineWidth: 2 }; series.marker = { radius: 4 }; series.label = { field: 'B', display: 'over', padding: 8, renderer: function(v) { return v + '%'; } }; series.renderer = function(sprite, cfg, rendererData, index) { var rec = rendererData.store.getAt(index); var val = rec.get('B'); if (val >= 80) { cfg.fillStyle = '#d9534f'; cfg.strokeStyle = '#d9534f'; } else { cfg.fillStyle = '#7cb342'; cfg.strokeStyle = '#7cb342'; } return cfg; }; } }); } 2. function chart.itemclick(chart, item, event, eOpts) { chart._selectedIndex = item.index; chart.getSeries().forEach(function(series) { series.getSprites().forEach(function(sprite) { sprite.setDirty(true); }); }); chart.redraw(); } Quote
AlexanderP Posted March 26 Author Posted March 26 1 hour ago, Sherzod said: Решение: 1. function chart.beforeInit(sender, config) { config.innerPadding = { left: 4, right: 10, top: 40 }; config.axes = [{ type: 'numeric', position: 'left', fields: ['A'], title: 'Count', grid: true }, { type: 'numeric', position: 'right', fields: ['B'], minimum: 0, maximum: 100, title: 'Percent', label: { renderer: function(v) { return v + '%'; } } }, { type: 'category', position: 'bottom', fields: ['LL'] }]; Ext.Array.each(config.series || [], function(series) { // BAR SERIES if (series.type === 'bar') { series.label = { field: 'A', display: 'outside', orientation: 'horizontal', padding: 10, renderer: function(v) { return Ext.util.Format.number(v, '0,000'); } }; series.renderer = function(sprite, cfg, rendererData, index) { var chart = sender; if (chart._selectedIndex !== undefined && chart._selectedIndex === index) { cfg.fillStyle = '#ff9800'; // выбранный } else { cfg.fillStyle = '#5fa2dd'; // обычный } return cfg; }; } // LINE SERIES if (series.type === 'line') { series.axis = 'right'; series.style = { strokeStyle: '#7cb342', lineWidth: 2 }; series.marker = { radius: 4 }; series.label = { field: 'B', display: 'over', padding: 8, renderer: function(v) { return v + '%'; } }; series.renderer = function(sprite, cfg, rendererData, index) { var rec = rendererData.store.getAt(index); var val = rec.get('B'); if (val >= 80) { cfg.fillStyle = '#d9534f'; cfg.strokeStyle = '#d9534f'; } else { cfg.fillStyle = '#7cb342'; cfg.strokeStyle = '#7cb342'; } return cfg; }; } }); } 2. function chart.itemclick(chart, item, event, eOpts) { chart._selectedIndex = item.index; chart.getSeries().forEach(function(series) { series.getSprites().forEach(function(sprite) { sprite.setDirty(true); }); }); chart.redraw(); } Спасибо! Отлично работает ddd.mp4 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.