Страницы

Поиск по вопросам

Показаны сообщения с ярлыком chart. Показать все сообщения
Показаны сообщения с ярлыком chart. Показать все сообщения

среда, 4 марта 2020 г.

Как правильно задать тип chart-а c помощью delphi

#delphi #excel #vba #chart #диаграммы


Есть часть кода на Delphi:  

chart:=sheet.chartobjects.add(270,205,397,220);
chart.chart.charttype:=4;
chart.Chart.SetSourceData(Sheet.Range['A3:B34']);


который выводит в Excel график (диаграмму):



Мне нужен другой тип графика, через макрос (excel-vba) он выглядит так:  

ActiveSheet.Shapes.AddChart2(332, xlLineMarkersStacked).Select


Вопрос: какой код на Delphi должен выполняться вместо этой строчки, чтоб он вывел
мне вот такой тип графика:

 
    


Ответы

Ответ 1



Вам достаточно заменить chart.chart.charttype:=4; на chart.chart.charttype:=66; // xlLineMarkersStacked = 66 чтобы сменить тип диаграммы на нужный. Если часто приходится использовать построение диаграмм в Excel внутри Delphi-программ, стоит завести модуль, где будут перечислены основные константы. Вот все константы энумерации для диаграмм Excel, скопируйте их в новый юнит, оформите как const и вам проще будет транслировать макросы Excel в код Delphi.

воскресенье, 12 января 2020 г.

Открыть файл в Javascript

#javascript #jquery #chart #jquery_file_upload


Я передаю табличные данные из html в excel с помощью tableExport.
Выглядит это так:

doExport = function () {
  _this.$el.tableExport($.extend({}, _this.options.exportOptions, {
    type: type,     // выбранный тип экспорта
  }));
};


Получается файл с дефолтным именем tableExport.xls, который создаётся в дефолтной
папке для загрузок, записывается, сохраняется и закрывается.

Понадобилось добавить после таблицы график. tableExport  для этого не предназначен.
Итого вопрос - как после выполнения tableExport мне обратиться к этому файлу? Его имя
остаётся дефолтным - но может добавляться порядковый номер. То есть имя я точно не
буду знать. Понимаю, что есть способ как-то запомнить путь и имя файла, но куда копать?
    


Ответы

Ответ 1



Вы не можете с помощью JS обратиться к файлу из файловой системы пользователя. Вам нужно как то добавить ваши данные до сохранения файла. Вероятно для этого придется разбираться в коде библиотеки и возможно модифицировать ее. Думаю лучшим решением будет сохранить график в отдельном файле.

четверг, 9 января 2020 г.

Как задать left position диаграммы во время экспорта в excel?

#delphi #excel #vba #chart #диаграммы


Делаю отчет в Excel-е с диаграммой на delphi.
У него фиксированная позиция:  

chart := sheet.chartobjects.add(270,205,397,220);


Как сделать, чтоб диаграмма началась с нужной мне колонки?
    


Ответы

Ответ 1



Амирхон, чтобы вам проще было работать в Delphi (да и в других программах) с офисными продуктами, постарайтесь разобраться в иерархии объектов. Как только вы разберетесь, многие вещи сразу станут понятны. Я не могу посоветовать вам какую-то конкретную книгу, поскольку сам когда-то разбирался методом научного тыка, но, возможно, кто-то другой посоветует. Хороший тон - использовать инструменты разработчика, они очень сильно помогают. В офисе 2003 и ранее - это запись макросов с последующим их анализом, позже - то же самое + использование вкладки Разработчик (её необходимо предварительно включить в настройках). Итак, Chart входит в семейство Shapes, которое принадлежит Sheet (принадлежащий, в свою очередь, Book). Фишка в том, что к одному и тому же объекту можно обратиться по-разному, OLE это позволяет. И тот факт, что у каждого программиста есть свои любимые подходы, порождает массу непонятного. Но стоит прочувствовать иерархию, всё становится на свои места. У меня подход несколько иной, чем у вас. Я вначале определяю объект, а уже затем задаю его свойства. На мой взгляд, так удобнее. Допустим, мы создали лист в Excel и заполнили несколько ячеек для диаграммы данными: Excel:=CreateOleObject('Excel.Application'); Excel.Visible:=True; Book:=Excel.Workbooks.Add; // мне не жалко переменных для каждого объекта Sheet:=Book.Worksheets[1]; // поскольку дальше проще работать for i := 1 to 5 do begin Sheet.Cells[i, 1].FormulaR1C1:=i; Sheet.Cells[i, 2].FormulaR1C1:=cos(i); // пусть будет косинус end; Все переменные здесь - OleVariant. Теперь создаем диаграмму: ch:=Sheet.Shapes.AddChart; Я специально выбрал для диаграммы переменную ch, а не chart, поскольку у диаграммы несколько уровней свойств, в том числе и свойство Chart, многие начинающие путаются в этом. Далее: Ch.Name := 'График 1'; // обзовём диаграмму так Ch.Chart.ChartType := xlLineMarkers; // тип диаграммы Типы диаграмм мы обсуждали в Как правильно задать тип chart-а c помощью delphi. Либо вы поступаете так, как я порекомендовал, либо можно использовать один из встроенных модулей Delphi, например, ExcelXP или Excel2010, в которых эти константы определены. Отмечу, что, чтобы изменить некоторые свойства диаграммы, например, название, я обращаюсь непосредственно к переменной ch, а вот для работы с графиком я должен уже обращаться к свойству Chart. Ну, а теперь вернемся к нашему основному вопросу. Изменим координаты. Координаты - свойства непосредственно диаграммы, это Left и Top. Задаются они в пикселях, причём только для левого верхнего угла, а правый нижний уже определяется Width и Height (шириной и высотой, причём, как правило, в долях экрана, а не в пикселях). Так как вам нужно поместить диаграмму не в координатах пикселей, а в координатах ячеек, то нам нужно вначале их рассчитать: Ch.Left := Sheet.Range['A1:D1', EmptyParam].Width + 2; Ch.Top := Sheet.Range['E1:E3', EmptyParam].Width + 2; Я поместил, таким образом, свою диаграмму в ячейку E4, сместив её край на 2 пикселя. Кстати, тот же самый результат можно получить по-другому: Ch.Left := Sheet.Range['E4', EmptyParam].Left + 2; Ch.Top := Sheet.Range['E4', EmptyParam].Top + 2; Что ещё раз демонстрирует разные подходы.

понедельник, 30 декабря 2019 г.

Как создать график в WPF?

#wpf #chart


Как создать график в WPF с координатами x,y и возможностью создания разных кривых?
Я пытался использовать Chart, но я не знаю как создать элемент Chart в коде.
    


Ответы

Ответ 1



Существует множество библиотек которые позволяют строить различные типы графиков в WPF - проектах. Несколько из них: OxyPlot LiveCharts Выбор языка программирования (F#) для небольших примеров по использованию оставил на свое усмотрение, так как не было указано явно какой предпочтительнее. 1. OxyPlot поддерживает различные типы графиков, среди которых LineSeries, PieSeries, BarSeries,...Из недостатков - слабая документация. Проблема существует уже давно, но, к сожалению, работа в этом направлении не ведется. Таким образом найти ответ на интересующий вопрос довольно сложно. Но так как библиотека уже завоевала определенную популярность, то по ней имеется не мало вопросов (с ответами :) ) на английском SO, которые должны помочь. Чтобы ответ был более полным рассмотрим простой пример - построение графиков двух функций sin и cos с возможностью отмечать галочками отображать обе линии, любую из них или не показывать вовсе. OxyPlot: xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" XAML: MainViewModel: open OxyPlot ... type MainViewModel() = let x = -5.0 let y = 5.0 let range = [x..0.1..y] let sindata = range |> List.map(fun value -> value, sin value) |> List.map(DataPoint) let cosdata = range |> List.map(fun value -> value, cos value) |> List.map(DataPoint) member __.SPoints = sindata member __.CPoints = cosdata 2. LiveCharts стремительно набирающая популярность библиотека. Из основных преимуществ - документация. Недостатки - баги, которые, впрочем, довольно успешно исправляются. Помимо стандартного набора типов графиков поддерживает 180° Gauge, Bubble series. Кроме этого планируется добавить поддержку некоторых других типов - Countour Maps. Если документации будет недостаточно, чтобы найти ответ на вопрос можно написать в чате (gitter). Пример практически аналогичный с предыдущим, только без возможности влиять на отображаемые графики. Связано с тем, что подобным привязка к элементам управления на данный момент не работает. Поэтому нужно создавать свойство в VM и связывать с ним. XAML: xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" VM: open LiveCharts open LiveCharts.Configurations type LiveChartsVM() = let x = -5.0 let y = 5.0 let range = [x..0.1..y] let sindata = range |> List.map(fun value -> value, sin value) |> ChartValues let cosdata = range |> List.map(fun value -> value, cos value) |> ChartValues do let mapper = Mappers.Xy().X(fst).Y(snd) LiveCharts.Charting.For(mapper, SeriesOrientation.Horizontal) member __.SPoints = sindata member __.CPoints = cosdata

пятница, 27 декабря 2019 г.

Xamarin график с AChartEngine

#android #c_sharp #xamarin #chart #график


Хочу нарисовать график, нашел бесплатную библиотеку AChartEngine. Однако демо который
там имеется реализован на java. Пытался импортировать этот проект в Android Studio,
но ругается на отсутствие gradle в проекте.

В примере встречается создание объектов интерфейса(что нельзя сделать в c#) и не
получается разобраться как происходит отрисовка самого графика. Понимаю, что рисуется
это в LinearLayout, но как это делается... 

Написал Main.axml по этому примеру

Main.axml



    
    
        
        
        
        
        


Ответы

Ответ 1



Давно пользовался этой библиотекой, насколько помню, следующий шаг должен быть: var view = new GraphicalView(context, lineChart) Т.е. создать view на базе графика и как обычно вставить его в разметку. Добавлено А это не этот же компонент, уже адаптированный под Xamarin? https://components.xamarin.com/view/achartengine

среда, 27 ноября 2019 г.

Как сделать сектора в пончике со скругленными углами?

#javascript #svg #canvas #chart #chart.js


  

Как это сделать?
Мне нужен мульти-сектор в пончике с закругленными концами и добавить тень самому
пончику.   

Хочу использовать chart.js, но можно и другие варианты без jquery. 
    


Ответы

Ответ 1



Есть вариант сделать с помощью SVG. На последней секции(#part4) в качестве примера заливка градиентом. UPD: Добавил еще вариант без CSS .circle { height: 200px; width: 200px; fill: none; stroke-width: 5; stroke-linecap: round; position: absolute; left:0; top:0; } #part1 { stroke: #172bc3; z-index: 3; transform: rotate(20deg); } #part2 { stroke: #f21d92; z-index: 2; transform: rotate(-70deg); } #part3 { stroke: #9631eb; z-index: 5; transform: rotate(-160deg); } #part4 { stroke: url(#gradient); z-index: 4; transform: rotate(-250deg); } #shadow { stroke: white; z-index:1; stroke-width: 2; }

Ответ 2



Решается вопрос с помощью SVG. Применил circles, вместо paths( почему бы и нет?:D ):

Ответ 3



Вариант SVG без CSS

Ответ 4



Решение с Chart.js начиная от 2.1.0+ Chart.pluginService.register({ afterUpdate: function (chart) { if (chart.config.options.elements.arc.roundedCornersFor !== undefined) { items=chart.config.options.elements.arc.roundedCornersFor; items.forEach(function(element) { var arc = chart.getDatasetMeta(0).data[element]; arc.round = { x: (chart.chartArea.left + chart.chartArea.right) / 2, y: (chart.chartArea.top + chart.chartArea.bottom) / 2, radius: (chart.outerRadius + chart.innerRadius) / 2, thickness: (chart.outerRadius - chart.innerRadius) / 2 - 1, backgroundColor: arc._model.backgroundColor } }); } }, afterDraw: function (chart) { if (chart.config.options.elements.arc.roundedCornersFor !== undefined) { var ctx = chart.chart.ctx; items=chart.config.options.elements.arc.roundedCornersFor; items.forEach(function(element) { var arc = chart.getDatasetMeta(0).data[element]; var startAngle = Math.PI / 2 - arc._view.startAngle; var endAngle = Math.PI / 2 - arc._view.endAngle; ctx.save(); ctx.translate(arc.round.x, arc.round.y); ctx.fillStyle = arc.round.backgroundColor; ctx.beginPath(); //получаются артефакты //ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI); ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI); ctx.closePath(); ctx.fill(); ctx.restore(); }); } }, }); var settings = { type: 'doughnut', data: { labels: [], datasets: [{ data: [25, 25, 25,25], backgroundColor: [ "#363edc", "#48d0f0", "#9a31eb", "#f11e94" ], hoverBackgroundColor: [ "#363edc", "#48d0f0", "#9a31eb", "#f11e94" ] }] }, options: { rotation: 10, cutoutPercentage: 80, legend: { display: false }, tooltips: { enabled: false }, elements: { arc: { roundedCornersFor: [0,1,2,3] } } } }; var ctx = document.getElementById("myTest").getContext("2d"); var myChart = new Chart(ctx, settings);

Ответ 5



D3.js вариация, похожий ответ. Обратите внимание на заморочку, что бы перекрытие было не как в макете дизайнера, а правильно, в одну сторону. Похожие перекрытия в ответе господина @Pavel с решением на Chart.js let overlap = 0.2, duration = 1000, count = 2 + Math.floor(Math.random() * 5), data = Array(count).fill(0).map((d, i) => ({value: 1 + 5*Math.random()})); let svg = d3.select('#donut g'); let pie = d3.pie().sort(null); // let arc = d3.arc().innerRadius(70).outerRadius(85); let d = pie(data.map(d => d.value)); d.forEach(d => d.endAngle += overlap); drawArcs("right"); drawArcs("left"); function drawArcs(className) { let right = className === "right"; svg.selectAll("path." + className).data(d).enter() .append("path").classed(className, true) .attr("fill", (d, i) => `hsl(${i*77},75%,45%)`) .transition().duration(duration).attrTween('d', tween) function tween(d) { let center = (d.startAngle+d.endAngle)/2; let interpolator = d3.interpolate(center, right ? d.endAngle : d.startAngle) return t => { let v = interpolator(t); d.startAngle = right ? center - overlap*t : v; d.endAngle = right ? v : center + overlap*t; return arc.cornerRadius(10*t)(d); } } } UPD: по просьбам трудящихся добавил сделал вариант с анимацией заполнения в одну сторону. let overlap = 0.2, duration = 1000, count = 2 + Math.floor(Math.random() * 5), data = Array(count).fill(0).map((d, i) => ({value: 1 + 5*Math.random()})); let svg = d3.select('#donut g'); let pie = d3.pie().sort(null); // let arc = d3.arc().innerRadius(70).outerRadius(85); let d = pie(data.map(d => d.value)); d.forEach(d => d.endAngle += overlap); drawArcs("right"); drawArcs("left"); function drawArcs(className) { let right = className === "right"; svg.selectAll("path." + className).data(d).enter() .append("path").classed(className, true) .attr("fill", (d, i) => `hsl(${i*77},75%,45%)`) .transition().duration(duration).attrTween('d', tween) function tween(d) { let center = d.startAngle; let interpolator = d3.interpolate(center, right ? d.endAngle : d.startAngle) return t => { let v = interpolator(t); d.startAngle = right ? center : v; d.endAngle = right ? v : center + overlap*t; return arc.cornerRadius(10*t)(d); } } }

понедельник, 15 июля 2019 г.

Помогите правильно построить график Google Chart + nodejs

Здравствуйте, необходимо передать массив с сервера(nodejs) на клиент, чтобы потом по нему строить график. Я передаю массив, но на клиенте пишет, что это не массив. Где ошибка в коде?
Сервер:
app.post('/averageTimeInQueue', function(req, res, next) { var data = [ [2012, 1000, 400, 232], [2005, 1170, 460, 421], [2006, 660, 1120, 4324] ]; res.send(data); });
Клиент:
google.charts.load('current', {'packages':['line']}); google.charts.setOnLoadCallback(drawChart);
function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('number', 'Day'); data.addColumn('number', 'Guardians of the Galaxy'); data.addColumn('number', 'The Avengers'); data.addColumn('number', 'Transformers: Age of Extinction');
data.addRows(averageTimeInQueue); var options = { chart: { title: 'Box Office Earnings in First Two Weeks of Opening', subtitle: 'in millions of dollars (USD)' }, width: 600, height: 350, axes: { x: { 0: {side: 'top'} } } };
var chart = new google.charts.Line(document.getElementById('chart_div2'));
chart.draw(data, options); }
function averageTimeInQueue(){ var jsonData = $.ajax({ url: "/averageTimeInQueue", async: false, type: 'POST' }).responseText; return jsonData; }


Ответ

Конечно не массив, вы же его как текст отправляете. Сериализируйте его в json
на сервере res.send(JSON.stringify(data));
на клиенте data.addRows(averageTimeInQueue()) вместо data.addRows(averageTimeInQueue) и
var jsonData = $.ajax({ url: "/averageTimeInQueue", dataType: "json", async: false, type: 'POST' }).responseText; return JSON.parse(jsonData);

понедельник, 17 июня 2019 г.

Как растянуть диаграмму на весь MSChart в c#?

Проблема следующего характера: есть Chart с большим набором точек, необходимо изобразить график. Высота Chart может быть аж 2-3 тысячи единиц. После загрузки точек в Chart добавляется по оси OY дополнительное поле. Я выставила в ChartArea свойство position как Height = 100 и Widht = 100, т.е. тем самым, график должен был растянуться на весь Chart, но поле почему-то все-равно есть. Из Chart мне необходимо было убрать видимость линеек осей и начало координат должно начинаться с левого верхнего угла (сделала AxisY.IsReversed = true). Так вот как убрать эти "сопли"?


Ответ

Методом научного тыка нашёл свойство у Axis'ов которое отвечает за отображение черточек к которым стыкуются цифры...
В общем если выставить его в false то черточки пропадут:
area.AxisY.MajorTickMark.Enabled = false; area.AxisX.MajorTickMark.Enabled = false;
А чтобы убрать отступы по краям необходимо сделать следующее (по аналогии с Position): area.InnerPlotPosition= new ElementPosition(0, 0, 100, 100);

суббота, 15 июня 2019 г.

Winforms. Отобразить на графике разрешенные значения

Здравствуйте,
Поставил в форме график синуса и так же пытаюсь показать разрешенную площадь значений. Надо вывести на графике что-то похожее на серый прямоугольник (см. рис. 1) . Он не обязательно начинается с Y=0 Точки синуса приходят во время работы програмы одна за одной. Пытался использовать StripLine - очень похоже на то, что мне надо (см. рис. 2, желтоватая и голубоватая зоны), но у меня не получается определить его начальное значение как точку, в которой две координаты не равны 0. Так же его продолжительность должна быть не бесконечной. (В отличие от рис. 2)
рис. 1
рис. 2


Ответ

Благодаря одному из участников английского Stackoverflow, вот он ответ (точнее, работающий код) :
void drawAllowedArea(Point startPoint, Point endPoint, PaintEventArgs e) { var l = (float)chart1.ChartAreas[0].AxisX.ValueToPixelPosition(startPoint.X); var t = (float)chart1.ChartAreas[0].AxisY.ValueToPixelPosition(endPoint.Y); var r = (float)chart1.ChartAreas[0].AxisX.ValueToPixelPosition(endPoint.X); var b = (float)chart1.ChartAreas[0].AxisY.ValueToPixelPosition(startPoint.Y); var rect = RectangleF.FromLTRB(l, t, r, b); using (var br = new SolidBrush(Color.FromArgb(100, Color.Blue))) { e.Graphics.FillRectangle(br, rect.X, rect.Y, rect.Width, rect.Height); } e.Graphics.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width, rect.Height); }
//and use this function in chart1_Paint event: void chart1_Paint(object sender, PaintEventArgs e) { drawAllowedArea(new Point(20, 50000), new Point(40, 100000), e); }
Ссылка на мой вопрос: https://stackoverflow.com/questions/41263864/winforms-chart-draw-a-allowed-area-on-line-chart
Спасибо всем, кто думал как мне помочь! :)

понедельник, 20 мая 2019 г.

Как правильно задать тип chart-а c помощью delphi

Есть часть кода на Delphi:
chart:=sheet.chartobjects.add(270,205,397,220); chart.chart.charttype:=4; chart.Chart.SetSourceData(Sheet.Range['A3:B34']);
который выводит в Excel график (диаграмму):

Мне нужен другой тип графика, через макрос (excel-vba) он выглядит так:
ActiveSheet.Shapes.AddChart2(332, xlLineMarkersStacked).Select
Вопрос: какой код на Delphi должен выполняться вместо этой строчки, чтоб он вывел мне вот такой тип графика:


Ответ

Вам достаточно заменить
chart.chart.charttype:=4;
на
chart.chart.charttype:=66; // xlLineMarkersStacked = 66
чтобы сменить тип диаграммы на нужный.
Если часто приходится использовать построение диаграмм в Excel внутри Delphi-программ, стоит завести модуль, где будут перечислены основные константы. Вот все константы энумерации для диаграмм Excel, скопируйте их в новый юнит, оформите как const и вам проще будет транслировать макросы Excel в код Delphi.

вторник, 5 марта 2019 г.

Открыть файл в Javascript

Я передаю табличные данные из html в excel с помощью tableExport. Выглядит это так:
doExport = function () { _this.$el.tableExport($.extend({}, _this.options.exportOptions, { type: type, // выбранный тип экспорта })); };
Получается файл с дефолтным именем tableExport.xls, который создаётся в дефолтной папке для загрузок, записывается, сохраняется и закрывается.
Понадобилось добавить после таблицы график. tableExport для этого не предназначен. Итого вопрос - как после выполнения tableExport мне обратиться к этому файлу? Его имя остаётся дефолтным - но может добавляться порядковый номер. То есть имя я точно не буду знать. Понимаю, что есть способ как-то запомнить путь и имя файла, но куда копать?


Ответ

Вы не можете с помощью JS обратиться к файлу из файловой системы пользователя. Вам нужно как то добавить ваши данные до сохранения файла. Вероятно для этого придется разбираться в коде библиотеки и возможно модифицировать ее. Думаю лучшим решением будет сохранить график в отдельном файле.

понедельник, 18 февраля 2019 г.

Как задать left position диаграммы во время экспорта в excel?

Делаю отчет в Excel-е с диаграммой на delphi. У него фиксированная позиция:
chart := sheet.chartobjects.add(270,205,397,220);
Как сделать, чтоб диаграмма началась с нужной мне колонки?


Ответ

Амирхон, чтобы вам проще было работать в Delphi (да и в других программах) с офисными продуктами, постарайтесь разобраться в иерархии объектов. Как только вы разберетесь, многие вещи сразу станут понятны. Я не могу посоветовать вам какую-то конкретную книгу, поскольку сам когда-то разбирался методом научного тыка, но, возможно, кто-то другой посоветует.
Хороший тон - использовать инструменты разработчика, они очень сильно помогают. В офисе 2003 и ранее - это запись макросов с последующим их анализом, позже - то же самое + использование вкладки Разработчик (её необходимо предварительно включить в настройках).
Итак, Chart входит в семейство Shapes, которое принадлежит Sheet (принадлежащий, в свою очередь, Book). Фишка в том, что к одному и тому же объекту можно обратиться по-разному, OLE это позволяет. И тот факт, что у каждого программиста есть свои любимые подходы, порождает массу непонятного. Но стоит прочувствовать иерархию, всё становится на свои места.
У меня подход несколько иной, чем у вас. Я вначале определяю объект, а уже затем задаю его свойства. На мой взгляд, так удобнее. Допустим, мы создали лист в Excel и заполнили несколько ячеек для диаграммы данными:
Excel:=CreateOleObject('Excel.Application'); Excel.Visible:=True; Book:=Excel.Workbooks.Add; // мне не жалко переменных для каждого объекта Sheet:=Book.Worksheets[1]; // поскольку дальше проще работать for i := 1 to 5 do begin Sheet.Cells[i, 1].FormulaR1C1:=i; Sheet.Cells[i, 2].FormulaR1C1:=cos(i); // пусть будет косинус end;
Все переменные здесь - OleVariant. Теперь создаем диаграмму:
ch:=Sheet.Shapes.AddChart;
Я специально выбрал для диаграммы переменную ch, а не chart, поскольку у диаграммы несколько уровней свойств, в том числе и свойство Chart, многие начинающие путаются в этом. Далее:
Ch.Name := 'График 1'; // обзовём диаграмму так Ch.Chart.ChartType := xlLineMarkers; // тип диаграммы
Типы диаграмм мы обсуждали в Как правильно задать тип chart-а c помощью delphi. Либо вы поступаете так, как я порекомендовал, либо можно использовать один из встроенных модулей Delphi, например, ExcelXP или Excel2010, в которых эти константы определены. Отмечу, что, чтобы изменить некоторые свойства диаграммы, например, название, я обращаюсь непосредственно к переменной ch, а вот для работы с графиком я должен уже обращаться к свойству Chart
Ну, а теперь вернемся к нашему основному вопросу. Изменим координаты. Координаты - свойства непосредственно диаграммы, это Left и Top. Задаются они в пикселях, причём только для левого верхнего угла, а правый нижний уже определяется Width и Height (шириной и высотой, причём, как правило, в долях экрана, а не в пикселях). Так как вам нужно поместить диаграмму не в координатах пикселей, а в координатах ячеек, то нам нужно вначале их рассчитать:
Ch.Left := Sheet.Range['A1:D1', EmptyParam].Width + 2; Ch.Top := Sheet.Range['E1:E3', EmptyParam].Width + 2;
Я поместил, таким образом, свою диаграмму в ячейку E4, сместив её край на 2 пикселя. Кстати, тот же самый результат можно получить по-другому:
Ch.Left := Sheet.Range['E4', EmptyParam].Left + 2; Ch.Top := Sheet.Range['E4', EmptyParam].Top + 2;
Что ещё раз демонстрирует разные подходы.