* Writer に多系列の散布図 [#l390d6a8] Calc 以下なのに Writer です。 Writer のチャートは Writer ドキュメント上の表からデータを取得するものと、データを数値で埋め込むものの二種類があります。ここでは後者のデータで指定する方法で行います。 埋め込みドキュメントとしてチャートを作成したら、データを設定します。データは Calc の表で getDataArray メソッドの返り値と同じ並びの二次元配列で指定します。要するに、データは系列とは違うグループで並んでいます。 以下の例では、系列ごとのデータを X、Y データとして配列に入れたものを渡し、行と列を入れ替えてデータに設定します。 データシリーズを作成するときに指定するデータの表現は、Calc では Sheet1.A1:A10 などでしたが、この場合には 0, 1 ... などのようにデータシークエンスのインデックスで指定します (文字列で)。 ラベルはデータプロバイダが保持している ColumnDescriptions から指定します。指定は "label " + インデックスです。このとき、空の要素のインデックスを指定すると作成に失敗するので注意が必要です。 以下の例ではデータ系列を作成する前に ColumnDescriptions を変更しています。特定のラベルを指定したければ適当なところに入れておいて、そのインデックスを指定してください。UI で系列名を変更するとその値が変更されます。 後半の関数については [[OOoBasic/Calc/chart2/ex7]] を参照。 #code(basic){{ Sub InsertChartOnWriterDocumentExample chart_template = "com.sun.star.chart2.template.ScatterLineSymbol" ' 各配列が X, Y で二系列 data = Array(_ Array(Array(0, 1, 2, 3, 4, 5, 6, 7, 8), Array(10, 11, 13, 14, 12, 13, 10, 8, 7)), _ Array(Array(0.3, 1, 2.1, 3, 4, 4.2, 5.8, 7, 9), Array(10, 13, 16, 18, 13, 14, 15, 10, 19))) oDoc = ThisComponent oChart = InsertChartOnWriterDoc(oDoc, chart_template, data) 'mri oChart End Sub Function InsertChartOnWriterDoc(doc, template, data) oText = doc.getText oChartObj = doc.createInstance("com.sun.star.text.TextEmbeddedObject") oChartObj.CLSID = "12dcae26-281f-416f-a234-c3086127382e" oCursor = oText.createTextCursor() oText.insertTextContent(oCursor, oChartObj, False) chart = oChartObj.Model diagram = chart.getFirstDiagram data_provider = chart.getDataProvider color_scheme = diagram.getDefaultColorScheme chart_type_manager = chart.getChartTypeManager chart_type_template = chart_type_manager.createInstance(template) chart_type_template.changeDiagram(diagram) coords = diagram.getCoordinateSystems() coord = coords(0) chart_types = coord.getChartTypes() chart_type = chart_types(0) data_provider.setData(ExchangeData(data)) n = UBound(data) Dim series(n) ' ColumnDescriptions の書き換え Dim columns((n+1)*2-1) for i = 0 To (n+1) *2 -1 step 1 columns(i) = "Column " & CStr(i) next data_provider.setColumnDescriptions(columns) ' 系列を作成 For i = 0 To n step 1 s = create_scatter_series(data_provider, _ CStr(i*2), CStr(i*2+1), "label " & CStr(i*2+1)) s.Color = color_scheme.getColorByIndex(i) series(i) = s Next chart_type.setDataSeries(series) chart_type_template.changeDiagram(diagram)' # reset InsertChartOnWriterDoc = chart End Function Function create_scatter_series(provider, x_repr, y_repr, Optional label_repr) series = CreateUnoService("com.sun.star.chart2.DataSeries") ydata = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence") xdata = CreateUnoService("com.sun.star.chart2.data.LabeledDataSequence") ydata.setValues(create_data_sequence(provider, y_repr, "values-y")) if NOT IsMissing(label_repr) Then ydata.setLabel(create_data_sequence(provider, label_repr, "label")) end if xdata.setValues(create_data_sequence(provider, x_repr, "values-x")) series.setData(Array(ydata, xdata)) create_scatter_series = series End Function Function create_data_sequence(provider, repr, role) seq = nothing if provider.createDataSequenceByRangeRepresentationPossible(repr) Then seq = provider.createDataSequenceByRangeRepresentation(repr) seq.Role = role end If create_data_sequence = seq End Function ' データの入れ替え Function ExchangeData(data) Dim a(0) sn = UBound(data) series = (UBound(data) + 1) * 2 -1 s1 = data(0) n = UBound(s1(0)) Dim edata(n) for i = 0 to n step 1 a = Array() ReDim a(series) for j = 0 to sn step 1 s = data(j) x = s(0) y = s(1) a(j * 2) = x(i) a(j * 2+1) = y(i) next edata(i) = a next ExchangeData = edata End Function }} 系列のデータの長さが違う場合を考慮していませんが、その場合には nan となるようにデータプロバイダから NotANumber プロパティを取得、空のデータ値として入れます。 |