рдореИрдВ рдПрдХ рднрд░рд╛ рд╣реБрдЖ рд░реЗрдЦрд╛ рдЪрд╛рд░реНрдЯ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЖрдк рд▓реЛрдЧ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдЪрд┐рддреНрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦрд╛ рдФрд░ рд╡реЗ рд╡рд╛рдИ-рдЕрдХреНрд╖ рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП IFillFormatter рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреА рднрд░реА рд╣реБрдИ рд░реЗрдЦрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди, рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдерд┐рддрд┐ рдереА, рдЧрддрд┐рд╢реАрд▓ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВред рдореИрдВ рдпрд╣ рд╕реНрдерд┐рддрд┐ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдкрд░ рдХреИрд╕реЗ рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ == 0 рд╣реИ рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рднрд░реА рд╣реБрдИ рд╕реНрдерд┐рддрд┐ A рдХрд╛ рдЕрдВрдд рд╣реИ, рдпрджрд┐ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ == 1 рд╣реИ рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рднрд░реА рд╣реБрдИ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рдЕрдВрдд рдореВрд▓реНрдп рд╣реИред
рдпрд╛, рдКрдкрд░ рджрд┐рдП рдЧрдП рдЪрд┐рддреНрд░ рдХреА рддрд░рд╣ рдЪрд╛рд░реНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЕрдиреНрдп рд╕реБрдЭрд╛рд╡ред
drawLinearFill
рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдЬрд╣рд╛рдВ рдпрд╣ рднрд░рдг рд░реЗрдХреНрдЯ рдЦреАрдВрдЪрддрд╛ рд╣реИред рдпрд╣ generateFilledPath
рдФрд░ getFillLinePosition
рднреАрддрд░ рднрд░рдг рд░реЗрдХреНрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдкрдирд╛ рд░реЗрдХреНрдЯ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрди рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЖрдк рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреЗ рд╣реИрдВ
рдореИрдВрдиреЗ LineChartRenderer
рдХреЛ рдЙрдк-рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдХреЗ @ liuxuan30 рдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдФрд░ IFillFormatter
рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдмреА рд╣рд╛рд╕рд┐рд▓ рдХреА, рдЬреЛ рдореБрдЭреЗ рдлрд┐рд▓ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреВрд╕рд░рд╛ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдкрд╛рд╕ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрде рдмрдирд╛рдПрдВ (рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмреЗрдЬрд┐рдпрд░ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред
class AreaFillFormatter: IFillFormatter {
var fillLineDataSet: LineChartDataSet?
init(fillLineDataSet: LineChartDataSet) {
self.fillLineDataSet = fillLineDataSet
}
public func getFillLinePosition(dataSet: ILineChartDataSet, dataProvider: LineChartDataProvider) -> CGFloat {
return 0.0
}
public func getFillLineDataSet() -> LineChartDataSet {
return fillLineDataSet ?? LineChartDataSet()
}
}
class CustomLineChartRenderer: LineChartRenderer {
override open func drawLinearFill(context: CGContext, dataSet: ILineChartDataSet, trans: Transformer, bounds: XBounds) {
guard let dataProvider = dataProvider else { return }
let areaFillFormatter = dataSet.fillFormatter as? AreaFillFormatter
let filled = generateFilledPath(
dataSet: dataSet,
fillMin: dataSet.fillFormatter?.getFillLinePosition(dataSet: dataSet, dataProvider: dataProvider) ?? 0.0,
fillLineDataSet: areaFillFormatter?.getFillLineDataSet(),
bounds: bounds,
matrix: trans.valueToPixelMatrix)
if dataSet.fill != nil
{
drawFilledPath(context: context, path: filled, fill: dataSet.fill!, fillAlpha: dataSet.fillAlpha)
}
else
{
drawFilledPath(context: context, path: filled, fillColor: dataSet.fillColor, fillAlpha: dataSet.fillAlpha)
}
}
fileprivate func generateFilledPath(dataSet: ILineChartDataSet, fillMin: CGFloat, fillLineDataSet: ILineChartDataSet?, bounds: XBounds, matrix: CGAffineTransform) -> CGPath
{
let phaseY = animator?.phaseY ?? 1.0
let isDrawSteppedEnabled = dataSet.mode == .stepped
let matrix = matrix
var e: ChartDataEntry!
var fillLineE: ChartDataEntry?
let filled = CGMutablePath()
e = dataSet.entryForIndex(bounds.min)
fillLineE = fillLineDataSet?.entryForIndex(bounds.min)
if e != nil
{
if let fillLineE = fillLineE
{
filled.move(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
}
else
{
filled.move(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
}
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
}
// Create the path for the data set entries
for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1)
{
guard let e = dataSet.entryForIndex(x) else { continue }
if isDrawSteppedEnabled
{
guard let ePrev = dataSet.entryForIndex(x-1) else { continue }
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
}
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
}
// Draw a path to the start of the fill line
e = dataSet.entryForIndex(bounds.range + bounds.min)
fillLineE = fillLineDataSet?.entryForIndex(bounds.range + bounds.min)
if e != nil
{
if let fillLineE = fillLineE
{
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
}
else
{
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
}
}
// Draw the path for the fill line (backwards)
if let fillLineDataSet = fillLineDataSet {
for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1).reversed()
{
guard let e = fillLineDataSet.entryForIndex(x) else { continue }
if isDrawSteppedEnabled
{
guard let ePrev = fillLineDataSet.entryForIndex(x-1) else { continue }
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
}
filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
}
}
filled.closeSubpath()
return filled
}
}
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрджрд░реНрд╢ рдЙрджрд╛рд╣рд░рдг :)
рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рдХреИрд╕реЗ рд╣рд▓/рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ?
@ рд░реЛрдм-рдХреЗ рдХреНрдпрд╛ рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдореИрдВ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ:
let maxDataSet = LineChartDataSet()
let minDataSet = LineChartDataSet()
// ... fill the data sets
// Set the data
self.lineChart.data = LineChartData(dataSets: [maxDataSet, minDataSet])
// Set the custom line chart renderer
self.lineChart.renderer = CustomLineChartRenderer(dataProvider: self.lineChart, animator: self.lineChart.chartAnimator, viewPortHandler: self.lineChart.viewPortHandler)
maxDataSet.drawFilledEnabled = true
maxDataSet.fillFormatter = AreaFillFormatter(fillLineDataSet: minDataSet)
рдореИрдВрдиреЗ рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХрд╛ рдкрд╛рд▓рди рдХрд┐рдпрд╛, рдлрд┐рд░ рднреА рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ @ рд░реЛрдм-рдХреЗ
@ рд░реЛрдм-рдХреЗ рдореИрдВрдиреЗ CustomLineChartRenderer рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреНрд░реЗрдХ рдкреЙрдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ
рдореИрдВрдиреЗ LineChartRenderer
рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рдЕрдкрдбреЗрдЯ рдХреАред
рдЕрднреА рднреА рдХреЛрдИ рднрд╛рдЧреНрдп рдирд╣реАрдВ рд╣реИ рдпрд╛рд░ @ рд░реЛрдм-рдХреЗ
рдпрджрд┐ рдЖрдк ucbDataSet
рдФрд░ lcbDataSet
рдмреАрдЪ рдХрд╛ рд░рдВрдЧ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ рджреВрд╕рд░реЗ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЛ рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЗ рдлрд╝реЙрд░реНрдореЗрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рд╕реНрд╡рдпрдВ рдХреЗ рдлрд╝реЙрд░реНрдореЗрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:
ucbDataSet.fillFormatter = AreaFillFormatter(fillLineDataSet: lcbDataSet)
(рдпрд╛ рдлрд┐рд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд)
рдореИрдВ рдЬреЛ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдкрд╣рд▓реЗ рд╣реА рдХреЛрд╢рд┐рд╢ рдХрд░ рдЪреБрдХрд╛ рд╣реИ
рдореИрдВрдиреЗ CustomLineChartRenderer рдХреНрд▓рд╛рд╕ рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреНрд░реЗрдХ рдкреЙрдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ
рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдмреЗрдЬрд┐рдпрд░ рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
lineChartDataSet.mode = .horizontalBezier
ucbDataSet.mode = .horizontalBezier
lcbDataSet.mode = .horizontalBezier
рдореИрдВрдиреЗ рдЬреЛ рдХреЛрдб рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдореЛрдб рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдореЛрдб рдХреЛ .linear
рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ рдпрд╛ drawHorizontalBezier
рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдХреЛрдб рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
@ рд░реЛрдм-рдХреЗ рдиреЗ рдЗрд╕реЗ рдЕрднреА-рдЕрднреА рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ рдзрдиреНрдпрд╡рд╛рдж рдЗрд╕реЗ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдЖрджрдореА
рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?
рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?
рдХреНрдпрд╛ рдЖрдкрдХреЛ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛? рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯрд░реЗрдВрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рди рдХрд┐ LinearChartRender рдХрд╛, рдЗрд╕рд▓рд┐рдП рдХреЙрд▓ рдмреИрдХ рдХреЛ drawLinearFill
рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реЗрдВрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ
рд╡рд┐рдзрд┐ drawLinearFill
рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рдЬрдм рдЖрдк рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕рдореЗрдВ рдХрдИ рдирдП рд░реЗрдВрдбрд░ рд▓рдЧрддреЗ рд╣реИрдВ
рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?
рд╕рдорд╛рдзрд╛рди рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ: https://github.com/PhilJay/MPAndroidChart/issues/338
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдореИрдВрдиреЗ
LineChartRenderer
рдХреЛ рдЙрдк-рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдХреЗ @ liuxuan30 рдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдФрд░IFillFormatter
рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдмреА рд╣рд╛рд╕рд┐рд▓ рдХреА, рдЬреЛ рдореБрдЭреЗ рдлрд┐рд▓ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреВрд╕рд░рд╛ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдкрд╛рд╕ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрде рдмрдирд╛рдПрдВ (рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмреЗрдЬрд┐рдпрд░ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред