jQuery图表插件Flot
最近正在使用JQuery的flot進行畫圖,但是這方面的中文幫助實在是太少了,干脆把英文的document直接翻譯一下吧。因為也是再學習過程當中,難免會存在翻譯不準確的地方,如果文中描述的不明白的話,可以參考一下原文:http://people.iola.dk/olau/flot/API.txt
調用plot函數的方法如下:
var plot = $.plot(placeholder, data, options)Data的結構:
data應該是data series的一個數組:
[ series1, series2, ... ]
一個series可以是原始數據或者是擁有屬性的對象。原始數據是一個二維數組:
[ [x1, y1], [x2, y2], ... ]
為了簡化flot內容的邏輯關系,x軸和y軸的數值都要使用數字(當然,如果有特殊需要的話,flot也可以支持以時間一個軸,后面會有詳細的說明)。因 為大多數的情況下,我們都是從數據庫中直接提取數據并轉換成JSON格式,但是沒有關心過數據類型的問題。如果出現了奇怪的現象的話,請先檢查數據的格式 是否有問題。
如果在一個點的數據使用的是null的話,那么在繪制的過程中就會把這個點忽略。那么包含這個點的那條線就會有斷開的現象。這個點之前和之后的點是無法進行連接的。
線和點是相關連的。對于bars, 可以設置第三個關聯值(默認是0)。
一個單一的序列對象結構是:
除了其中的data以外,其它的屬性都沒有必要明確的指定,因為大多數情況下它們都是使用默認值的。通常你只指定標簽和數據:
{label: "y = 3",data: [[0, 3], [10, 3]] }label是說明這一個數據序列的含義的,如果只有一個序列的話就沒有必要設置這個屬性。如果有多個序列,就要設置label,從而可以在圖中區分出序列的含義。
如果不設置color,那么會自動生成color來進行顯示。
如果你想讓用戶添加和刪除數據序列的話,剩下的屬性就非常有用了。
xaxis和yaxis選項設置使用哪個維度,默認是設置成1的,如果設置成2的話,就使用第二個維度(x軸在上面,y軸在右邊)。
?
clickable和hoverable可以設置成false,當整個圖表設置成可交互時,這個選項可以讓這條特定的數據序列讓用戶無法交互。
?
沒有說明的屬性會在后面詳細介紹,大多數情況話都是使用默認值。當你要使用自己定義的值時,就會把默認的值給覆蓋。
這是一個比較復雜的數據序列定義:
Options的含義:
所有的選項都是完全可選的。如果想要修改的話,把它當作一個對象來處理就可以了:
可定制說明部分的用戶設置:
legend: {show: booleanlabelFormatter: null or (fn: string, series object -> string)labelBoxBorderColor: colornoColumns: numberposition: "ne" or "nw" or "se" or "sw"margin: number of pixels or [x margin, y margin]backgroundColor: null or colorbackgroundOpacity: number between 0 and 1container: null or jQuery object/DOM element/jQuery expression }說明可以看成是一個表格,由兩部分組成的:一個是所有數據序列的label,另一個是顏色。如果想讓label以其它的格式顯示的話,可以使用lavelFormatter這個函數:
?
labelFormatter: function(label, series) { // series is the series object for the label return '<a href="#' + label + '" mce_href="#' + label + '">' + label + '</a>'; }noColums是要把這個說明部分劃分成幾列。position是要把這個說明放到圖表的哪個位置(top-right, top-left, 等等)以及與其它圖表之間的距離。backgroundColor和backgroundOpacity是設置背景的顏色和透明度,正常都是默認的。
如果你想把這個說明部分從圖表中拿到來,并放到DOM中的一個元素中的話,就可以設置container這個屬性,它可以是一個JQuery的對象或者表達式。psition和margin等等的一些屬性就會被忽略,而且這個元素中的內容會被重寫的。
關于軸的用戶設置:
xaxis, yaxis: {show: null or true/falseposition: "bottom" or "top" or "left" or "right"mode: null or "time"color: null or color spectickColor: null or color specmin: null or numbermax: null or numberautoscaleMargin: null or numbertransform: null or fn: number -> numberinverseTransform: null or fn: number -> numberticks: null or number or ticks array or (fn: range -> ticks array)tickSize: number or arrayminTickSize: number or arraytickFormatter: (fn: number, object -> string) or stringtickDecimals: null or numberlabelWidth: null or numberlabelHeight: null or numberreserveSpace: null or truetickLength: null or numberalignTicksWithAxis: null or number }所有的都包含相同的屬性。下面會詳細的介紹每一個屬性的含義。
show:如果不設置這個屬性的話,flot會自動的來選擇,比如:數據與軸有關系的話,那么就會把軸顯示出來,當然更靈活的方式還是用
true或者false來設定這個屬性。
position:用來定義軸文字顯示的位置,是在X軸的上方還是下方,是在Y軸的左邊還是右邊。
mode:軸的數據類型,默認的是數值類型,當設置成time類型的話,就可以用時間做為一個軸。
color:定義軸標識文字和坐標的顏色。如果不設置的話,就與圖表中網格的顏色是相同的。當然也可以自己來設置顏色,使用"tickColor"還
可以單獨定義坐標的顏色。
min/max:描述軸最大值和最小值范圍。如果不設置的話,flot會自動的計算并生成一個范圍來進行顯示。
autoscaleMargin:這個有一點難理解。flot自動計算min/max的范圍的時候會加上一個值,從而防止有的點會放到圖的邊緣。這個屬性只能
在不設置max/min的時候才可以使用。如果設置了一個margin,flot會延長軸的結束點從而構成一個完整的坐標。默認的設置是x軸沒有margin,y軸有0.02的margin。默認的設置已經可以滿足大多數的使用了。
"transform","inverseTransform":可以對原始的數據進行一些特殊的計算以后再進行繪制。比如:可以通過這種方法來繪制一些非線性
的曲線。例如:
xaxis: {transform: function (v) { return Math.log(v); },inverseTransform: function (v) { return Math.exp(v); } }同樣的,想對Y軸做反轉的話就可以:
yaxis: {transform: function (v) { return -v; },inverseTransform: function (v) { return -v; } }Flot中的數據都是單調的,也就是說原始的數據是不能出現亂序的。inverseTransform就是transform的反向函數,通過顯示的數據可以得到原始數據,如果圖表沒有交互過程的話,這個屬性可以不用設置。
?剩下的選項都是處理刻度的。如果不對刻度進行任何的設置的話,坐標生成函數會自動的計算刻度。算法會先估算刻度的個數,再計算出兩個刻度之間的間隔大小, 從而可以生成完整的刻度了。你可以給算法設置刻度的個數("ticks"),算法會根據原始數據的范圍返回一個最接近你設置的刻度數的一個值,也就是說如 果你設置了3,那么它返回5個坐標也是很正常的,因為算法認為5個刻度會更合適。如果不設置刻度的話,把"ticks"設置成0或者空數組就可以了。還可 以通過設置"tickSize"來定義兩個刻度之間的差值,如果設置成2,那么刻度就會是2,4,6. 通過"minTickSize"可以設置兩個刻度差值的最小值。對于時間刻度,我們可以設置數組來完成:[2, "month"]。
最狠的方法還是直接忽略flot自帶的算法,完全使用數組自己定義的刻度:
????? ticks: [0, 1.2, 2.4]
下面的方法會更加的可定制化:
????? ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]
Flot還支持更牛X的可擴展性,就是可以調用一個函數來形成各個刻度的值。在函數中需要通過最小值,最大值和自己設定的一個間隔來計算出一個數組,作為各個刻度:
function piTickGenerator(axis) {var res = [], i = Math.floor(axis.min / Math.PI);do {var v = i * Math.PI;res.push([v, i + "\u03c0"]);++i;} while (v < axis.max);return res; }還可以設置"tickDecimals"來指定刻度顯示的精度。 ??? 給"tickFormatter"定義也一個函數可以靈活的格式化刻度的顯示,函數有兩個參數,一個是刻度的值,一個是軸上的最大值和最小值,返回值一定要是string類型:
function formatter(val, axis) {return val.toFixed(axis.tickDecimals);}對于一個軸對象,有min和max這兩個屬性,還有"tickDecimals"是坐標顯示的精度,"tickSize"是兩個刻度之間的差值,有了這么多的屬性,就可以自己定制刻度的顯示內容:
function suffixFormatter(val, axis) {if (val > 1000000)return (val / 1000000).toFixed(axis.tickDecimals) + " MB";else if (val > 1000)return (val / 1000).toFixed(axis.tickDecimals) + " kB";elsereturn val.toFixed(axis.tickDecimals) + " B"; }"labelWidth"和"labelHeight"是定義刻度顯示區域的。"reserveSpace"的意思是即使你不定義軸,flot也會 使用這個屬性把軸占用的空間給預留出來。當繪制單行多軸圖表時與"labelWidth"和"labelHeight"一起使用會得到很多的效果。
"tickLength"定義坐標刻度的長度,null是默認設置,也就是一個很小的刻度,如果設置成0,在軸上就不會顯示刻度。
"alignTicksWithAxis":如果設置成其它軸的數字,Flot會在自動生成刻度的時候會與其它軸上的刻度對齊的。這樣會更加的美觀,尤其是圖中有網格,并且有多具軸的時候,非常的實用。
繪制多個軸:
如果你需要繪制多個軸的話,數據序列就要按照下面的格式給出,{ data: [...], yaxis: 2 }表明這個序列要使用第二個Y軸。這時要設置軸的顯示形式的話,就不能直接使用xaxis/yaxis的選項了,而是要有兩個數組:
如果所有的Y軸都想設置成相同的值的話,使用yaxis: { min: 0 }就可以了。
時間類型的數據序列:
============================
時間序列比數據序列就有一點難了。因為時間序列并不是按照10進制來排列的,所以Flot需要把時間轉換成數值,再進行處理。Flot是通過 javascript中的timestamps來支持時間序列的。timestamp是一個時間距1970年1月1日00:00:00的毫秒數,類似與 Unix系統中使用的timestamps,只不過javascript的單位是毫秒,unix的意單位是秒。可以通過下面的來獲取瀏覽器的 timestamp:
alert((new Date()).getTime())
一般來說,大家都希望在網頁上顯示本地的時間,但是Flot只能把timestamp轉換成UTC的時間來顯示,所以唯一的方法就是獲取本瀏覽當前的 timestamp,和時區,再對timestamp的值進行計算,從而得到UTC時間與當前時間相等時的UTC timestamp。再把轉換后的值提供給Flot來繪圖。
這時就可以用轉換后的timestamp來構造原始的數據的,并把軸的類型定義成"time",Flot就可以自動的計算刻度并格式化它們。當然了,也可以自己定義刻度,但是一定要使用數值型的參數,不能是對象類型。刻度的生成和格式化也可以通過軸的選項來自定義:
月份的名字是可以自定義的:
monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]當"twelveHourClock"被設置成true時,時間就會用12時制來顯示。 時間的格式和月份的名字是被一個flot自帶的格式化函數使用的,它會使用一個數據對象,一個格式字符串,從而返回格式化后的字符串。還可以直接調 用$.plot.formatDate(date, formatstring, monthNames)或者調用自己完成的具有更強大功能的函數。
你還可以通過函數來控制刻度的顯示內容。下面的例子是把December 24格式化成24/12:
tickFormatter: function (val, axis) {var d = new Date(val);return d.getUTCDate() + "/" + (d.getUTCMonth() + 1); }對于時間模式的"tickSize"是有一點特別的"minTickSize",需要使用數組來定義,格式為"[value, unit]"。其中,unit只能是"second", "minute", "hour", "day", "month" and "year",所以就可以這樣來設置了:
? minTickSize: [1, "month"]
這樣就可以把兩個刻度之間的差值設置成最小一個月了,如果tickSize是[2, "day"],那么刻度的差值就是固定了兩天了。 自定義數據序列
"series: {}"的選項會拷貝到所有的數據序列中。如果想設置所有的數據序列顯示屬性的話,就可以在這個全局選項中設置,如果只想設置某一個數據序列的顯示的話,就可以在對應的序列中進行設置。 "lines", "points"和"bars"這三個屬性的設置是很重要的,因為會直接影響到點,線和柱狀圖的顯示方式。如果所有的屬性都沒有設置的話,flot會有一個默認的設置。當然也可以單獨的設置一個或者多個屬性,flot會根據你的設置來繪制圖表:
var options = {series: {lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },points: { show: true, fill: false }} };"lineWidth"設置線的寬度,單位是pixels。你還可以把這個值設置成0,從而會把線刪除,當然陰影也不會繪制。
"fill"是控制填充的,當線足夠寬的話,線就變成了圖形,所以就有必要確定是否要填充了。 "fillColor"確定填充的顏色,如果這個值不設置的話,flot會使用數據序列中定義的顏色來填充。第4個值是設置填充的透明度,取值從0(完全透明)到1(不透明). 對于bar類型的柱狀圖而言,fillColor可以是階梯形式的,下面會有詳細的介紹。"barWidth"是柱的寬度,單位就是對應軸的數據類 型。當軸是時間類型的話,那么單位就是毫秒,那么24 * 60 * 60 * 1000的寬度就是一天。"align"是柱的對齊方式,左對齊(默認)或者居中。當"horizontal"被設置以后,柱狀圖就會水平繪制,也就是柱 與x軸是平行的。如果之前已經繪制過與y軸平行的柱子的話,還要交換一下坐標軸。
對于線而言,"steps"用來設置兩個相鄰點之間是使用直線連接還是使用臺階線連接。如果使用臺階線的,flot會自動的添加一些點來實現這個功能。
對于繪制的點,可以設置點的半徑和符號。目前flot只支持圓形的符號,可以使用其它的插件來使用其它的符號,也可以使用自己定義的函數:
輸入的參數是繪制的上下文,繪制點x和y軸的坐標,radius設置繪制點的半徑,也可以設置是否顯示陰影。
"shadowSize"用來設置陰影的大小,單位是pixels,設置成0的話就可以刪除陰影。
"colors"數組是用來設置在繪圖過程中各條線使用的顏色的默認值:
? colors: ["#d18b2c", "#dba255", "#919733"]
如果數據序列的數量比定義的顏色數量多的話,flot還會生成一些新的顏色用于繪制圖表。
自定義網格
grid: {show: booleanaboveData: booleancolor: colorbackgroundColor: color/gradient or null labelMargin: numberaxisMargin: numbermarkings: array of markings or (fn: axes -> array of markings)borderWidth: numberborderColor: color or nullminBorderMargin: number or nullclickable: booleanhoverable: booleanautoHighlight: booleanmouseActiveRadius: number }網格可以看做是軸上的刻度不斷的延長而形成的。網格大多數的屬性都是在軸中定義的,但是也有些屬性是網格獨自定義的,"color"用來定義顏 色,"backgroundColor"用來定義網格中的背景顏色。如果設置成null的話,就說明grid的背景是透明的,當然也可以設置成梯度的。
當然也把show設置成false,而不顯示所有的刻度標簽和網格。"aboveData"用來確定網格與數據的層次關系。
"labelMargin"是刻度標簽與軸之間的像素值,"axisMargin"是兩個軸之間的像素值,當有兩個軸相鄰的時候使用的。你可以使用CSS來定義刻度標簽的顯示格式,需要定義一個"tickLabel"的CSS類。
"borderWidth"是圖表的邊界寬度值。設置成0就沒有邊界。"borderColor"是定義邊界的顏色,"minBorderMargin"控制邊界的最小空白區域。
"markings"用來繪制圖表中的簡單直線和背景上的矩形區域。可以使用數組來設置要繪制的線或者區域{ xaxis: { from, to }, yaxis: { from, to } }。或者是一個可以返回這種數組的函數,參數是軸的數據作為一個對象。
還可以設置矩形區域的顏色:
如果省略其中的一個值的話,那么flot就會把省略值的范圍設置成對應軸的所有取值范圍。{ xaxis: {
from: 0, to: 2 } }就會繪制一個x軸從0到2, Y軸全部的矩形。markings: [ { yaxis: { from: 1, to: 1 } }, ... ]就會繪制一條與x軸平行的直線。可以通過設置"lineWidth"改變線的寬度。
使用函數來設置的話可以這樣來實現:
把"clickable"設置成true, 圖表就會監聽鼠標的click動作,并生成"plotclick"事件,參數是點擊的坐標和點擊距離最近的數值,位置的坐標可以是圖表中對應的值,也可以是全局頁面的坐標。
同樣的,如果把"hoverable"設置成true的話,圖表就會監聽鼠標的移動事件,并生成"plothover",參數與"plotclick"是 相同的。如果"autoHighlight"設置成true,鼠標附近的元素就會被高亮顯示。當然你也可以把"autoHighlight"設置成 false,從而可以使用highlight/unhighlight函數來進行設置。
"plotclick" 和 "plothover"的處理函數可以這樣完成:
其中item對象的格式是
item: {datapoint: the point, e.g. [0, 2]dataIndex: the index of the point in the data arrayseries: the series objectseriesIndex: the index of the seriespageX, pageY: the global screen coordinates of the point }如果設置的數據是這樣子的:
$.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);而且鼠標與(7, 3)這個節點離的非常近,"datapoint" 是 [7, 3],"dataIndex" 會是1。"series"就是一個序列的對象,包含的信息是"Foo" (series.label)和顏色(series.color),seriesIndex的值是0. 如果使用上面的方法來顯示一些信息的話,那么就需要監聽"mouseout"事件。"mouseActiveRadius"用來定義鼠標做用的范圍。如果有多個數據點在這個范圍中的話,Flot只會選擇最接近的那一個。對柱狀圖而言,最高的那個柱子會被選中。
如果不想有交互的話,就可以"hoverable" 和 "clickable" 設置成false:{ data: [...], label: "Foo", clickable: false }。
梯度顏色的定義
===================
定義的方法:
如果想讓網格的背景從黑色到灰色的話:
grid: {backgroundColor: { colors: ["#000", "#999"] }}對數據序列,可以設置顏色的透明度和亮度:
{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }第一個只有透明度,第二個還包含了亮度。對于柱形圖來說,下面的例子可以讓柱子逐漸的消失:
?
Flot目前只能支持垂直方向上從上到下的漸變,因為IE只支持這個模式。
Plot方法
---------------
由plot函數生成的對象提供了可調用的方法
? - highlight(series, datapoint)
用來高亮顯示一個數據點。你可以通過"plotclick"事件獲取對象,或者使用highlight(1, 3)來高亮顯示第2個數據序列中的第4個數據點。
? - unhighlight(series, datapoint) or unhighlight()
刪除高亮顯示,如果有參數的話,就是刪除指定高亮的點,如果沒有參數的話,plot就會刪除圖表中所有的高亮顯示。
? - setData(data)
用來重新設置數據。但是軸的取值范圍,刻度坐標,標簽是不會重新繪制的,可以調用draw()讓plot繪制新的曲線,但是其它部分不會改變。用這個函數可以變速的更新一個圖表中的曲線,前提條件是所有值的取值范圍是沒有改變的。
? - setupGrid()
重新計算軸的取值范圍,并設置刻度和標簽。如果調用過setData的話,就可以使用這個函數重新繪制有影響的部分。
? - draw()
重新繪制圖表中的顯示曲線部分。
? - triggerRedrawOverlay()
在可繪制區域上更新可交互的部分,如選擇區域和點的高亮。當要自己編寫插件時是非常有用的。圖表并不會馬上重新繪制,而是可以設置一個定時器來獲取多次的重給事件。
? - width()/height()
獲取可繪制區域的寬度和高度。也就是網格中的區域。
? - offset()
返回網格中可繪圖的區域相對于整個文檔的偏移,當計算鼠標所在的位置時很重要。把event.pageX/Y減去這個偏移就是在繪圖區域中的坐標。
? - pointOffset({ x: xpos, y: ypos })
(x,y)這個數據點在包含繪圖div窗口中的偏移。
? - resize()
如果繪圖窗口的大小發生改變,就可以調用這個函數來重新繪圖。
? - shutdown()
關閉已經注冊的所有事件的處理函數。
還會一些其它的函數,但是需要你了解Flot內部的代碼流程。如果你修改了獲取到對象中的屬性的話,那么你就修改了Flot內部使用的對象,Flot無法及時的更新你修改的內容,還有可能會影響繪圖功能,所以使用的時候一定要小心。具體的使用方法可以參考原版的文檔。
? - getData()
? - getAxes()
? - getPlaceholder()
? - getCanvas()
? - getPlotOffset()
? - getOptions()
Hooks(鉤子函數)
======================
Plot對象在繪制過程中可以添加許多的鉤子函數,從而添加一些方法,在方法還可以訪問Flot中的內部數據。
下面就是Flot處理流程的概要:
1. 插件的初始化,處理各個選項
2. 構造繪圖區域
3. 設置各類數據:處理用戶錄入的數據,計算顯示用的顏色,把原始數據轉化成內部格式,規格化數據,查看最大最小值用來設置軸的取值范圍。
4. 網格的設置:計算軸的空間,刻度,刻度的標簽。
5. 繪圖: 繪制網格,按照順序繪圖
6. 設置事件處理的自定義函數
7. 答復事件。
8. 關閉:一般都是發生在整個圖表被重寫的時候發生。
鉤子函數一個簡單的函數,并放在了一個特定的數組當中。你可以使用"hooks"來添加鉤子函數,當繪圖完成以后,鉤子函數仍然是起作用的,因為它的定義已經存在于plot的對象中了。
?
// define a simple draw hookfunction hellohook(plot, canvascontext) { alert("hello!"); };// pass it in, in an array since we might want to specify severalvar plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } });// we can now find it again in plot.hooks.draw[0] unless a plugin // has added other hooks下面會列出所有可以設置鉤子的地方。所有的鉤子都會把plot對象作為第一個參數。你可以在在Flot綁定的插件中看使用的例子。
?- processOptions? [phase 1]
?? function(plot, options)
當Flot處理合并完合選項后調用。當你不想僅僅簡單的合并默認的選項時就可以使用。插件也可以通過這個函數來打開或者關閉與自己相關的選項。
?- processRawData? [phase 3]
?? function(plot, series, data, datapoints)
在Flot復制并且格式化原始數據之前調用。如果函數中使用格式化的數據點設置了datapoints.points并把datapoints.pointsize設置成數據點的數量,那么Flot就會不會對這個數據序列進行任何的處理。
一般來說,你可能會設置datapoints.format,用來定義數據值的格式化方法和軸取值的范圍。默認的格式化數組是這樣子的:
第一個對象的含義是對于第一個坐標軸,需要計算x軸的取值范圍,必須是數字類型,而且是必選的。如果是空的,或者無法轉換成數字類型的話,所有的點都會被 初始化成0.當然了你還可以指定"defaultValue",如果沒有指定類型的話,Flot就會使用這里定義的選項值。
processDatapoints [phase 3]function(plot, series, datapoints)在格式化完原始數據之后,查找最大值和最小值之前。這個鉤子函數是用來對數據進行轉換的。"datapoints"包含了兩個成員,其中 datapoints.points是格式化后的一維數組,datapoints.pointsize是所有數據點的個數。這里給出一個簡單的轉換,把所 有的點的y坐標都乘以2:
?
function multiply(plot, series, datapoints) {var points = datapoints.points, ps = datapoints.pointsize;for (var i = 0; i < points.length; i += ps)points[i + 1] *= 2; }一定要保證datapoints中數據的正確性,因為Flot不會再為這些數據進行檢查的。
?- drawSeries? [phase 5]
?? function(plot, canvascontext, series)
只用來繪制一個數據序列,在循環的繪制每一個數據序列之前調用。
?- draw? [phase 5]
?? function(plot, canvascontext)
在網格繪制完成以后被調用。可以閱讀原代碼來學習這個方法的使用。
?- bindEvents? [phase 6]
?? function(plot, eventHolder)
在Flot配置它的事件處理函數之后調用。可以給eventHolder設置需要的事件處理函數。例如:
用來繪制可交互區域的。
?- shutdown? [phase 8]
?? function (plot, eventHolder)
當plot.shutdown()時被調用,一般只有整個繪圖被一個新的繪圖完全覆蓋時才需要。
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/longyi/archive/2013/06/12/3132603.html
總結
以上是生活随笔為你收集整理的jQuery图表插件Flot的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 乌鲁木齐万科都会传奇三期是毛坯房还是精装
- 下一篇: 武汉长江青年城是毛坯房还是精装修?