Top > OOoBasic > Calc > chart2 > ex8

Writer に多系列の散布図 Edit

Calc 以下なのに Writer です。

Writer のチャートは Writer ドキュメント上の表からデータを取得するものと、データを数値で埋め込むものの二種類があります。ここでは後者のデータで指定する方法で行います。

埋め込みドキュメントとしてチャートを作成したら、データを設定します。データは Calc の表で getDataArray メソッドの返り値と同じ並びの二次元配列で指定します。要するに、データは系列とは違うグループで並んでいます。

以下の例では、系列ごとのデータを X、Y データとして配列に入れたものを渡し、行と列を入れ替えてデータに設定します。 データシリーズを作成するときに指定するデータの表現は、Calc では Sheet1.A1:A10 などでしたが、この場合には 0, 1 ... などのようにデータシークエンスのインデックスで指定します (文字列で)。

ラベルはデータプロバイダが保持している ColumnDescriptions から指定します。指定は "label " + インデックスです。このとき、空の要素のインデックスを指定すると作成に失敗するので注意が必要です。 以下の例ではデータ系列を作成する前に ColumnDescriptions を変更しています。特定のラベルを指定したければ適当なところに入れておいて、そのインデックスを指定してください。UI で系列名を変更するとその値が変更されます。

後半の関数については OOoBasic/Calc/chart2/ex7 を参照。

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
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 プロパティを取得、空のデータ値として入れます。


Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes